diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-07-27 12:25:46 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-07-27 12:25:46 +0200 |
| commit | 56f3b8161f73c33fe6e25f6461d3f061af427e9e (patch) | |
| tree | 7abe54aa45b3b4d9e3db0a75564d75c0d44b06ce /internal/caldata/caldata.go | |
| parent | a8232892b0ec94f8d077e3730143a09efcac452d (diff) | |
| download | lectio-56f3b8161f73c33fe6e25f6461d3f061af427e9e.tar.gz lectio-56f3b8161f73c33fe6e25f6461d3f061af427e9e.zip | |
feat(caldata): embed + parse the owned universal Roman calendar (initial coverage)
Diffstat (limited to 'internal/caldata/caldata.go')
| -rw-r--r-- | internal/caldata/caldata.go | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/internal/caldata/caldata.go b/internal/caldata/caldata.go new file mode 100644 index 0000000..5deb895 --- /dev/null +++ b/internal/caldata/caldata.go @@ -0,0 +1,69 @@ +// Package caldata embeds and parses lectio's owned universal General Roman +// Calendar data into a calendar.Layer. It imports only internal/ini and +// internal/calendar (types). +package caldata + +import ( + _ "embed" + "fmt" + + "github.com/lukaszkasprzak/lectio/internal/calendar" + "github.com/lukaszkasprzak/lectio/internal/ini" +) + +//go:embed roman-calendar.ini +var romanCalendar []byte + +// Universal parses the embedded universal calendar. It panics on a malformed +// embedded file (a build-time bug caught by tests), never at the request layer. +func Universal() calendar.Layer { + l, err := parse(romanCalendar) + if err != nil { + panic(fmt.Sprintf("caldata: embedded roman-calendar.ini invalid: %v", err)) + } + return l +} + +func parse(data []byte) (calendar.Layer, error) { + secs, err := ini.Parse(data) + if err != nil { + return calendar.Layer{}, err + } + layer := calendar.Layer{Cels: map[string]calendar.RawCelebration{}} + for _, s := range secs { + fields := map[string]string{} + for _, p := range s.Pairs { + fields[p.Key] = p.Val + } + switch { + case s.Name == "" && len(fields) == 0: + continue + case s.Name == "layer": + layer.ID, layer.Name, layer.Type = fields["id"], fields["name"], fields["type"] + default: + base, variant, isVariant := cutVariant(s.Name) + rc := layer.Cels[base] + if rc.Fields == nil { + rc = calendar.RawCelebration{Fields: map[string]string{}, Variants: map[string]map[string]string{}} + } + if isVariant { + rc.Variants[variant] = fields + } else { + for k, v := range fields { + rc.Fields[k] = v + } + } + layer.Cels[base] = rc + } + } + return layer, nil +} + +func cutVariant(name string) (base, variant string, ok bool) { + for i := 0; i < len(name); i++ { + if name[i] == '/' { + return name[:i], name[i+1:], true + } + } + return name, "", false +} |
