1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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" }
|