Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33
@@ -372,9 +372,9 @@ f, err := fejkdata.New(fejkdata.WithDataFS(svse.Modules()...))
|
||||
```
|
||||
|
||||
Two locales are `WithDataFS(append(svse.Modules(), enus.Modules()...)...)`. To stand in your
|
||||
own places, pass the locale's `FS` alone beside a tree providing `geo.SE.address` with the
|
||||
columns that port, `street`, `street-number`, `postal-code` and `locality`:
|
||||
`WithDataFS(svse.FS, myPlaces)`. `New` fails where no `WithDataFS` or `WithDataPath` names the
|
||||
own places, pass the locale's `FS` alone beside a tree providing `geo.SE.address`, a record
|
||||
with a `format` and the columns `sv_SE.address` reads, `street`, `street-number`,
|
||||
`postal-code` and `locality`: `WithDataFS(svse.FS, myPlaces)`. `New` fails where no `WithDataFS` or `WithDataPath` names the
|
||||
data to load.
|
||||
|
||||
`New` refuses data that breaks the grammar, could mean two things or cannot render a valid
|
||||
|
||||
@@ -13,11 +13,13 @@ import (
|
||||
)
|
||||
|
||||
// Source is one tree to load, from the root of an fs.FS. label prefixes file names in
|
||||
// errors; onDisk marks label as a directory that must exist.
|
||||
// errors; onDisk marks label as a directory that must exist; at is the folder fsys mounts the
|
||||
// tree at, "" for its root.
|
||||
type Source struct {
|
||||
fsys fs.FS
|
||||
label string
|
||||
onDisk bool
|
||||
at string
|
||||
}
|
||||
|
||||
// Dir is the tree in the directory path, its errors labelled with it.
|
||||
@@ -30,8 +32,9 @@ func FS(fsys fs.FS) Source { return Source{fsys: fsys} }
|
||||
|
||||
// Mounted is s with its tree under the folders the dot path namespace spells, "" for none.
|
||||
func (s Source) Mounted(namespace string) Source {
|
||||
if namespace != "" {
|
||||
s.fsys = mounted{fsys: s.fsys, at: strings.ReplaceAll(namespace, ".", "/")}
|
||||
if namespace != "" && s.at == "" {
|
||||
s.at = strings.ReplaceAll(namespace, ".", "/")
|
||||
s.fsys = mounted{fsys: s.fsys, at: s.at}
|
||||
}
|
||||
return s
|
||||
}
|
||||
@@ -48,14 +51,14 @@ type Category struct {
|
||||
// ReadRows reads a rows file beside the category.
|
||||
func (c Category) ReadRows(name string) (string, error) { return c.rows.read(name) }
|
||||
|
||||
// labelled is the file p as errors name it: under the source's label, as the labelled tree
|
||||
// spells it, below any mount.
|
||||
// labelled is the file p as errors name it: a labelled source's as its own tree spells it,
|
||||
// below the mount.
|
||||
func (s Source) labelled(p string) string {
|
||||
if s.label == "" {
|
||||
return p
|
||||
}
|
||||
if m, isMounted := s.fsys.(mounted); isMounted {
|
||||
p, _ = m.inner(p)
|
||||
if inner, below := underMount(s.at, p); below {
|
||||
p = inner
|
||||
}
|
||||
return path.Join(s.label, p)
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ func (s Source) Manifest() (Manifest, error) {
|
||||
if err := s.check(); err != nil {
|
||||
return Manifest{}, err
|
||||
}
|
||||
b, err := fs.ReadFile(s.fsys, ManifestFile)
|
||||
b, err := fs.ReadFile(s.fsys, path.Join(s.at, ManifestFile))
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return Manifest{}, nil
|
||||
}
|
||||
@@ -50,12 +50,7 @@ func (s Source) Manifest() (Manifest, error) {
|
||||
}
|
||||
|
||||
// ManifestPath is the manifest's path as errors name it.
|
||||
func (s Source) ManifestPath() string {
|
||||
if m, isMounted := s.fsys.(mounted); isMounted {
|
||||
return s.labelled(path.Join(m.at, ManifestFile))
|
||||
}
|
||||
return s.labelled(ManifestFile)
|
||||
}
|
||||
func (s Source) ManifestPath() string { return s.labelled(path.Join(s.at, ManifestFile)) }
|
||||
|
||||
// decodeManifest decodes a manifest, refusing any key or shape it does not define, and
|
||||
// reports every mistake: first each entry's own, in path order, then each parent naming
|
||||
|
||||
@@ -45,11 +45,22 @@ func (m mounted) ReadDir(name string) ([]fs.DirEntry, error) {
|
||||
|
||||
// inner is name as fsys spells it, where name lies at or below at.
|
||||
func (m mounted) inner(name string) (string, bool) {
|
||||
if name == m.at {
|
||||
inner, below := underMount(m.at, name)
|
||||
return inner, below && fs.ValidPath(name)
|
||||
}
|
||||
|
||||
// underMount is name as the tree mounted at at spells it, where name lies at or below at.
|
||||
func underMount(at, name string) (string, bool) {
|
||||
switch name {
|
||||
case at:
|
||||
return ".", true
|
||||
case "":
|
||||
return name, false
|
||||
}
|
||||
rest, below := strings.CutPrefix(name, m.at+"/")
|
||||
return rest, below && fs.ValidPath(name)
|
||||
if at == "" {
|
||||
return name, true
|
||||
}
|
||||
return strings.CutPrefix(name, at+"/")
|
||||
}
|
||||
|
||||
// towards is the folder below name on the way to at, where name lies above at.
|
||||
|
||||
Reference in New Issue
Block a user