summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-08-11 22:33:34 +0200
committerThomas Voss <mail@thomasvoss.com> 2024-08-11 22:33:34 +0200
commit574fd098228f5b63d10a4a739ee7b8e6c668a671 (patch)
tree171ec68e046af60af0861ac42eeb6dc54138f7e7
parenta0c502e3a1490e5b69bb550f2fb4f79fadfa34b7 (diff)
More work on mintages
-rw-r--r--cmd/mfmt/main.go25
-rw-r--r--lib/mintage/parser.go32
-rw-r--r--lib/mintage/parser_test.go44
-rw-r--r--main.go16
-rw-r--r--template/coins_mintages.templ34
5 files changed, 90 insertions, 61 deletions
diff --git a/cmd/mfmt/main.go b/cmd/mfmt/main.go
index cb9b0cd..263b258 100644
--- a/cmd/mfmt/main.go
+++ b/cmd/mfmt/main.go
@@ -50,17 +50,20 @@ func mfmt(path string, in io.Reader, out io.Writer) error {
}
fmt.Fprintf(out, `BEGIN %d`, data.StartYear)
- if len(data.Circ) != 0 {
- fmt.Fprintln(out, "\n\nBEGIN CIRC")
- formatSection(out, data.Circ)
- }
- if len(data.BU) != 0 {
- fmt.Fprintln(out, "\n\nBEGIN BU")
- formatSection(out, data.BU)
- }
- if len(data.Proof) != 0 {
- fmt.Fprintln(out, "\n\nBEGIN PROOF")
- formatSection(out, data.Proof)
+ for i, tbl := range data.Tables {
+ if len(tbl) != 0 {
+ var section string
+ switch mintage.CoinType(i) {
+ case mintage.TypeCirculated:
+ section = "CIRC"
+ case mintage.TypeNIFC:
+ section = "BU"
+ case mintage.TypeProof:
+ section = "PROOF"
+ }
+ fmt.Fprintf(out, "\n\nBEGIN %s\n", section)
+ formatSection(out, tbl)
+ }
}
fmt.Fprintln(out, "")
diff --git a/lib/mintage/parser.go b/lib/mintage/parser.go
index 4c5e6f9..fb92e64 100644
--- a/lib/mintage/parser.go
+++ b/lib/mintage/parser.go
@@ -9,6 +9,15 @@ import (
"unicode"
)
+type CoinType int
+
+const (
+ TypeCirculated CoinType = iota
+ TypeNIFC
+ TypeProof
+ coinTypes
+)
+
const (
_ = -iota
Unknown // Unknown mintage
@@ -33,8 +42,8 @@ type Row struct {
}
type Set struct {
- StartYear int
- Circ, BU, Proof []Row
+ StartYear int
+ Tables [coinTypes][]Row
}
func (r Row) Label() string {
@@ -46,8 +55,8 @@ func (r Row) Label() string {
func Parse(reader io.Reader, file string) (Set, error) {
var (
- data Set // Our data struct
- slice *[]Row // Where to append mintages
+ data Set
+ ctype CoinType = -1
)
scanner := bufio.NewScanner(reader)
@@ -77,11 +86,11 @@ func Parse(reader io.Reader, file string) (Set, error) {
switch arg {
case "CIRC":
- slice = &data.Circ
+ ctype = TypeCirculated
case "BU":
- slice = &data.BU
+ ctype = TypeNIFC
case "PROOF":
- slice = &data.Proof
+ ctype = TypeProof
default:
if !isNumeric(arg, false) {
return Set{}, SyntaxError{
@@ -113,7 +122,7 @@ func Parse(reader io.Reader, file string) (Set, error) {
fallthrough
case isNumeric(tokens[0], true), tokens[0] == "?":
switch {
- case slice == nil:
+ case ctype == -1:
return Set{}, SyntaxError{
expected: "coin type declaration",
got: tokens[0],
@@ -146,10 +155,11 @@ func Parse(reader io.Reader, file string) (Set, error) {
}
row := Row{Mintmark: mintmark.s}
- if len(*slice) == 0 {
+ if len(data.Tables[ctype]) == 0 {
row.Year = data.StartYear
} else {
- row.Year = (*slice)[len(*slice)-1].Year
+ rows := data.Tables[ctype]
+ row.Year = rows[len(rows)-1].Year
if row.Mintmark == "" || mintmark.star {
row.Year++
}
@@ -162,7 +172,7 @@ func Parse(reader io.Reader, file string) (Set, error) {
row.Cols[i] = atoiWithDots(tok)
}
}
- *slice = append(*slice, row)
+ data.Tables[ctype] = append(data.Tables[ctype], row)
default:
return Set{}, SyntaxError{
expected: "‘BEGIN’ directive or mintage row",
diff --git a/lib/mintage/parser_test.go b/lib/mintage/parser_test.go
index dd78c71..3cc8ea3 100644
--- a/lib/mintage/parser_test.go
+++ b/lib/mintage/parser_test.go
@@ -28,7 +28,7 @@ func TestParserComplete(t *testing.T) {
data.StartYear)
}
- for i, row := range data.Circ {
+ for i, row := range data.Tables[TypeCirculated] {
for j, col := range row.Cols {
var n int
if i == 1 && j == 1 {
@@ -37,12 +37,12 @@ func TestParserComplete(t *testing.T) {
n = 1000*i + j + 1000
}
if col != n {
- t.Fatalf("Expected data.Circ[i][j]=%d; got %d", n, col)
+ t.Fatalf("Expected data.Tables[TypeCirculated][i][j]=%d; got %d", n, col)
}
}
}
- for i, row := range data.BU {
+ for i, row := range data.Tables[TypeNIFC] {
for j, col := range row.Cols {
var n int
if i == 1 && j == 1 {
@@ -51,12 +51,12 @@ func TestParserComplete(t *testing.T) {
n = 1000*i + j + 1100
}
if col != n {
- t.Fatalf("Expected data.BU[i][j]=%d; got %d", n, col)
+ t.Fatalf("Expected data.Tables[TypeNIFC][i][j]=%d; got %d", n, col)
}
}
}
- for i, row := range data.Proof {
+ for i, row := range data.Tables[TypeProof] {
for j, col := range row.Cols {
var n int
if i == 1 && j == 1 {
@@ -65,19 +65,19 @@ func TestParserComplete(t *testing.T) {
n = 1000*i + j + 1200
}
if col != n {
- t.Fatalf("Expected data.Proof[i][j]=%d; got %d", n, col)
+ t.Fatalf("Expected data.Tables[TypeProof][i][j]=%d; got %d", n, col)
}
}
}
- if len(data.Circ) != 2 {
- t.Fatalf("Expected len(data.Circ)=2; got %d", len(data.Circ))
+ if len(data.Tables[TypeCirculated]) != 2 {
+ t.Fatalf("Expected len(data.Tables[TypeCirculated])=2; got %d", len(data.Tables[TypeCirculated]))
}
- if len(data.BU) != 2 {
- t.Fatalf("Expected len(data.BU)=2; got %d", len(data.BU))
+ if len(data.Tables[TypeNIFC]) != 2 {
+ t.Fatalf("Expected len(data.Tables[TypeNIFC])=2; got %d", len(data.Tables[TypeNIFC]))
}
- if len(data.Proof) != 2 {
- t.Fatalf("Expected len(data.Proof)=2; got %d", len(data.Proof))
+ if len(data.Tables[TypeProof]) != 2 {
+ t.Fatalf("Expected len(data.Tables[TypeProof])=2; got %d", len(data.Tables[TypeProof]))
}
}
@@ -96,8 +96,8 @@ func TestParserNoProof(t *testing.T) {
t.Fatalf(`Expected err=nil; got "%s"`, err)
}
- if len(data.Proof) != 0 {
- t.Fatalf("Expected len(data.Proof)=0; got %d", len(data.Proof))
+ if len(data.Tables[TypeProof]) != 0 {
+ t.Fatalf("Expected len(data.Tables[TypeProof])=0; got %d", len(data.Tables[TypeProof]))
}
}
@@ -114,7 +114,7 @@ func TestParserMintmarks(t *testing.T) {
t.Fatalf(`Expected err=nil; got "%s"`, err)
}
- for i, row := range data.Circ {
+ for i, row := range data.Tables[TypeCirculated] {
for j, col := range row.Cols {
var n int
if i > 0 && j == 1 {
@@ -123,21 +123,21 @@ func TestParserMintmarks(t *testing.T) {
n = 1000*i + j + 1000
}
if col != n {
- t.Fatalf("Expected data.Circ[i][j]=%d; got %d", n, col)
+ t.Fatalf("Expected data.Tables[TypeCirculated][i][j]=%d; got %d", n, col)
}
}
}
for i, y := range [...]int{2020, 2021, 2021} {
- if data.Circ[i].Year != y {
- t.Fatalf("Expected data.Circ[%d].Year=%d; got %d",
- i, y, data.Circ[i].Year)
+ if data.Tables[TypeCirculated][i].Year != y {
+ t.Fatalf("Expected data.Tables[TypeCirculated][%d].Year=%d; got %d",
+ i, y, data.Tables[TypeCirculated][i].Year)
}
}
for i, s := range [...]string{"", "KNM", "MdP"} {
- if data.Circ[i].Mintmark != s {
- t.Fatalf(`Expected data.Circ[%d].Mintmark="%s"; got "%s"`,
- i, s, data.Circ[i].Mintmark)
+ if data.Tables[TypeCirculated][i].Mintmark != s {
+ t.Fatalf(`Expected data.Tables[TypeCirculated][%d].Mintmark="%s"; got "%s"`,
+ i, s, data.Tables[TypeCirculated][i].Mintmark)
}
}
}
diff --git a/main.go b/main.go
index 21a3b1a..270eabb 100644
--- a/main.go
+++ b/main.go
@@ -111,15 +111,27 @@ func mintageHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
countries := lib.SortedCountries(
r.Context().Value("printer").(lib.Printer))
- code := cmp.Or(r.FormValue("c"), countries[0].Code)
+ code := strings.ToLower(cmp.Or(r.FormValue("code"), countries[0].Code))
+ ctype := strings.ToLower(cmp.Or(r.FormValue("type"), "circ"))
path := filepath.Join("data", "mintages", code)
f, _ := os.Open(path) // TODO: Handle error
defer f.Close()
set, _ := mintage.Parse(f, path) // TODO: Handle error
+ var idx mintage.CoinType
+ switch ctype {
+ case "circ":
+ idx = mintage.TypeCirculated
+ case "nifc":
+ idx = mintage.TypeNIFC
+ case "proof":
+ idx = mintage.TypeProof
+ }
+
ctx := context.WithValue(r.Context(), "code", code)
- ctx = context.WithValue(ctx, "set", set)
+ ctx = context.WithValue(ctx, "type", ctype)
+ ctx = context.WithValue(ctx, "table", set.Tables[idx])
ctx = context.WithValue(ctx, "countries", countries)
next.ServeHTTP(w, r.WithContext(ctx))
})
diff --git a/template/coins_mintages.templ b/template/coins_mintages.templ
index b6ed2de..47940e1 100644
--- a/template/coins_mintages.templ
+++ b/template/coins_mintages.templ
@@ -17,7 +17,7 @@ var denoms = [...]float64{
templ CoinsMintages() {
{{
code := ctx.Value("code").(string)
- set := ctx.Value("set").(mintage.Set)
+ table := ctx.Value("table").([]mintage.Row)
p := ctx.Value("printer").(lib.Printer)
}}
<header>
@@ -45,7 +45,7 @@ templ CoinsMintages() {
<div class="grid">
<label for="country-dd">
{ p.T("Country") }
- <select id="country-dd" name="c">
+ <select id="country-dd" name="code">
for _, c := range ctx.Value("countries").
([]lib.Country) {
<option
@@ -58,18 +58,9 @@ templ CoinsMintages() {
</select>
</label>
<fieldset>
- <label for="compact-circ">
- <input id="compact-circ" type="checkbox" name="circ" checked/>
- { p.T("Circulation Coins") }
- </label>
- <label for="compact-nifc">
- <input id="compact-nifc" type="checkbox" name="nifc"/>
- { p.T("NIFC / BU Sets") }
- </label>
- <label for="compact-proof">
- <input id="compact-proof" type="checkbox" name="proof"/>
- { p.T("Proof Coins") }
- </label>
+ @coinTypeRadio("circ", p.T("Circulation Coins"))
+ @coinTypeRadio("nifc", p.T("NIFC / BU Sets"))
+ @coinTypeRadio("proof", p.T("Proof Coins"))
</fieldset>
</div>
<button type="submit">{ p.T("Filter") }</button>
@@ -83,7 +74,7 @@ templ CoinsMintages() {
}
</thead>
<tbody>
- for _, row := range set.Circ {
+ for _, row := range table {
<tr>
<th scope="col">
if row.Mintmark != "" {
@@ -110,3 +101,16 @@ templ CoinsMintages() {
</section>
</main>
}
+
+templ coinTypeRadio(short, long string) {
+ <label for={ "compact-" + short }>
+ <input
+ id={ "compact-" + short }
+ type="radio"
+ name="type"
+ value={ short }
+ checked?={ ctx.Value("type").(string) == short }
+ />
+ { long }
+ </label>
+}