diff --git a/meta/domain.go b/meta/domain.go new file mode 100644 index 000000000..c7ee00a38 --- /dev/null +++ b/meta/domain.go @@ -0,0 +1,77 @@ +package meta + +import ( + "sort" + "strings" +) + +const ( + domainName int = iota + domainDescription + domainLast +) + +var domainHeaders Header = map[string]int{ + "Domain": domainName, + "Description": domainDescription, +} + +type Domain struct { + Name string + Description string +} + +type DomainList []Domain + +func (d DomainList) Len() int { return len(d) } +func (d DomainList) Swap(i, j int) { d[i], d[j] = d[j], d[i] } +func (d DomainList) Less(i, j int) bool { return d[i].Name < d[j].Name } + +func (d DomainList) encode() [][]string { + var data [][]string + + data = append(data, domainHeaders.Columns()) + + for _, row := range d { + data = append(data, []string{ + row.Name, + row.Description, + }) + } + + return data +} + +func (d *DomainList) decode(data [][]string) error { + if !(len(data) > 1) { + return nil + } + + var domains []Domain + + fields := domainHeaders.Fields(data[0]) + for _, row := range data[1:] { + d := fields.Remap(row) + + domains = append(domains, Domain{ + Name: strings.TrimSpace(d[domainName]), + Description: strings.TrimSpace(d[domainDescription]), + }) + } + + *d = DomainList(domains) + + return nil +} + +func LoadDomains(path string) ([]Domain, error) { + var d []Domain + + if err := LoadList(path, (*DomainList)(&d)); err != nil { + return nil, err + } + + sort.Sort(DomainList(d)) + + return d, nil +} diff --git a/meta/domains_test.go b/meta/domains_test.go new file mode 100644 index 000000000..78000820f --- /dev/null +++ b/meta/domains_test.go @@ -0,0 +1,17 @@ +package meta + +import ( + "testing" +) + +func TestDomain(t *testing.T) { + t.Run("check domains", testListFunc("testdata/domains.csv", &DomainList{ + Domain{ + Name: "coastal", + Description: "Coastal Tsunami Gauge Network", + }, + Domain{ + Name: "gnss", + }, + })) +} diff --git a/meta/generate/main.go b/meta/generate/main.go index 852cb0b37..89b1f369a 100644 --- a/meta/generate/main.go +++ b/meta/generate/main.go @@ -23,6 +23,7 @@ func main() { "deployedDataloggers": {"DeployedDatalogger"}, "deployedReceivers": {"DeployedReceiver"}, "doases": {"InstalledDoas"}, + "domains": {"Domain"}, "features": {"Feature"}, "firmwareHistory": {"FirmwareHistory"}, "gains": {"Gain"}, @@ -58,6 +59,7 @@ func main() { "assets": {"Asset", []string{"make", "model", "serial"}}, "citations": {"Citation", []string{"key"}}, "classes": {"Class", []string{"station"}}, + "domains": {"Domain", []string{"name"}}, "darts": {"Dart", []string{"station"}}, "marks": {"Mark", []string{"code"}}, "monuments": {"Monument", []string{"mark"}}, diff --git a/meta/set.go b/meta/set.go index 582c569b4..b1a637157 100644 --- a/meta/set.go +++ b/meta/set.go @@ -52,6 +52,7 @@ const ( VisibilityFile = "environment/visibility.csv" CitationsFile = "references/citations.csv" + DomainsFile = "references/domains.csv" ) // SetPathMap is used to manipulate the filepath inside the Set. @@ -105,6 +106,7 @@ type Set struct { visibilities VisibilityList citations CitationList + domains DomainList } func (s *Set) files() map[string]List { @@ -152,6 +154,7 @@ func (s *Set) files() map[string]List { VisibilityFile: &s.visibilities, CitationsFile: &s.citations, + DomainsFile: &s.domains, } } diff --git a/meta/set_auto.go b/meta/set_auto.go index d185e3899..376b0ed9c 100644 --- a/meta/set_auto.go +++ b/meta/set_auto.go @@ -70,6 +70,11 @@ func (s Set) Doases() []InstalledDoas { return s.doases } +// Domains is a helper function to return a slice of Domain values. +func (s Set) Domains() []Domain { + return s.domains +} + // Features is a helper function to return a slice of Feature values. func (s Set) Features() []Feature { return s.features @@ -255,6 +260,17 @@ func (s Set) Dart(station string) (Dart, bool) { return Dart{}, false } +// Domain is a helper function to return a Domain value and true if one exists. +func (s Set) Domain(name string) (Domain, bool) { + for _, v := range s.domains { + if name != v.Name { + continue + } + return v, true + } + return Domain{}, false +} + // Mark is a helper function to return a Mark value and true if one exists. func (s Set) Mark(code string) (Mark, bool) { for _, v := range s.marks { diff --git a/meta/testdata/domains.csv b/meta/testdata/domains.csv new file mode 100644 index 000000000..d1a69097b --- /dev/null +++ b/meta/testdata/domains.csv @@ -0,0 +1,3 @@ +Domain,Description +coastal,Coastal Tsunami Gauge Network +gnss, diff --git a/tests/domains_test.go b/tests/domains_test.go new file mode 100644 index 000000000..6899e8834 --- /dev/null +++ b/tests/domains_test.go @@ -0,0 +1,34 @@ +package delta_test + +import ( + "testing" + + "github.com/GeoNet/delta" + "github.com/GeoNet/delta/meta" +) + +var domainChecks = map[string]func(*meta.Set) func(t *testing.T){ + "check for duplicate domains": func(set *meta.Set) func(t *testing.T) { + return func(t *testing.T) { + domains := make(map[string]interface{}) + for _, s := range set.Domains() { + if _, ok := domains[s.Name]; ok { + t.Errorf("domain %s is duplicated", s.Name) + } + domains[s.Name] = true + } + } + }, +} + +func TestDomains(t *testing.T) { + + set, err := delta.New() + if err != nil { + t.Fatal(err) + } + + for k, v := range domainChecks { + t.Run(k, v(set)) + } +}