diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-03 23:30:12 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-03 23:30:12 +0200 |
| commit | d45d0b4e4534253d782cc6312d7edda43cca196d (patch) | |
| tree | 79a8e1c554d0a4960f9217b28986e3f6df2b2864 /mobile | |
| parent | d7da4b09f7775276231d0241cfe2700d247728ee (diff) | |
| download | lectio-d45d0b4e4534253d782cc6312d7edda43cca196d.tar.gz lectio-d45d0b4e4534253d782cc6312d7edda43cca196d.zip | |
baseline: track the gomobile engine facade as-is
mobile/mobile.go and its go.mod/go.sum additions were sitting untracked in
the working tree. Recorded here unchanged so the work that follows has a
diff baseline; no lines of it are modified by this commit.
Also ignore the cmd/dlectio-gen build product and the SDD scratch dir.
Diffstat (limited to 'mobile')
| -rw-r--r-- | mobile/mobile.go | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/mobile/mobile.go b/mobile/mobile.go new file mode 100644 index 0000000..c2c6347 --- /dev/null +++ b/mobile/mobile.go @@ -0,0 +1,112 @@ +// Package mobile is lectio's engine facade for the dlectio Android app. It is +// bound to a native Android library with gomobile: +// +// gomobile bind -target=android/arm64 -tags fullbible \ +// -o dlectio-engine.aar github.com/lukaszkasprzak/lectio/mobile +// +// The app calls Day() with a plain date/form/version and receives one JSON +// document with the day's identity and rendered Mass readings. All liturgical +// computation and text resolution happens here, in the exact validated lectio +// engine — the app does none of it. Keep every exported signature to types +// gomobile can marshal (string in, string out): that is why the payload is JSON. +package mobile + +import ( + "encoding/json" + "strings" + + "github.com/lukaszkasprzak/lectio/internal/config" + "github.com/lukaszkasprzak/lectio/internal/readings" + "github.com/lukaszkasprzak/lectio/internal/render" +) + +// reading is one Mass reading, rendered in the requested corpus. +type reading struct { + Ord int `json:"ord"` + Part string `json:"part"` // machine key, e.g. "ewangelium" / "psalm" + Heading string `json:"heading"` // human label in the interface language, e.g. "Gospel" + Citation string `json:"citation"` + Text string `json:"text"` +} + +// dayDoc is the JSON returned by Day. +type dayDoc struct { + Date string `json:"date"` + Form string `json:"form"` + Lang string `json:"lang"` + Version string `json:"version"` + Name string `json:"name"` + Season string `json:"season"` + Colour string `json:"colour"` + Readings []reading `json:"readings"` + Error string `json:"error,omitempty"` +} + +// lectByForm maps the app's form code to lectio's lectionary value. +func lectByForm(form string) string { + if form == "ef" { + return "traditional" + } + return "new" +} + +// Day computes one day's identity and Mass readings and returns them as JSON. +// +// date - "YYYY-MM-DD" +// form - "of" (Ordinary) or "ef" (1962) +// version - corpus: "drb" | "wuj" | "vul" | "grb" +// lang - interface language for the celebration name: "en" | "pl" +// +// It never panics: any engine error is reported in the JSON "error" field so the +// JNI boundary always returns a well-formed string. +func Day(date, form, version, lang string) string { + lect := lectByForm(form) + out := dayDoc{Date: date, Form: form, Lang: lang, Version: version} + + // Day identity (name/season/colour) in the interface language. + cfgID := config.Config{UILanguage: lang, Lectionary: lect, All: true} + if _, info, err := readings.Load(cfgID, readings.Options{Date: date, All: true}); err == nil { + out.Name = info.Name + out.Season = info.Season + out.Colour = info.Colour + } else { + out.Error = err.Error() + } + + // Readings, resolved and rendered in the requested corpus. The interface + // language localizes the structural labels (Heading) and citation dialect; + // the corpus (version) alone decides the scripture text. + cfgR := config.Config{UILanguage: lang, Lectionary: lect, ReadingVersion: version, All: true} + secs, _, err := readings.Load(cfgR, readings.Options{Date: date, All: true}) + if err != nil { + if out.Error == "" { + out.Error = err.Error() + } + } else { + for i, sec := range secs { + // GatherVersion's lang localizes only the label/error wording, never + // the verse text (which the corpus alone decides), so the interface + // language is correct here. HeadingWithRef gives the same localized + // "label (citation)" heading lectio shows in its cli/tui/web. + _, blocks := render.GatherVersion(version, sec, lect, lang) + out.Readings = append(out.Readings, reading{ + Ord: i, + Part: sec.PartID, + Heading: render.HeadingWithRef(sec, lang), + Citation: sec.Citation, + Text: strings.Join(blocks, "\n"), + }) + } + } + + b, err := json.Marshal(out) + if err != nil { + // Should be impossible with these types; degrade gracefully. + return `{"error":"marshal failed"}` + } + return string(b) +} + +// Ping is a trivial JNI smoke test: it returns "pong" so the app can confirm the +// native engine loaded before issuing a real query. +func Ping() string { return "pong" } |
