diff --git a/tools/exp/main.go b/tools/exp/main.go index 8a65c84..9d77af8 100644 --- a/tools/exp/main.go +++ b/tools/exp/main.go @@ -9,6 +9,7 @@ import ( "github.com/cjslep/activity/tools/exp/rdf" "github.com/cjslep/activity/tools/exp/rdf/owl" "github.com/cjslep/activity/tools/exp/rdf/rdfs" + "github.com/cjslep/activity/tools/exp/rdf/rfc" "github.com/cjslep/activity/tools/exp/rdf/schema" "github.com/cjslep/activity/tools/exp/rdf/xsd" "io/ioutil" @@ -33,6 +34,7 @@ func init() { mustAddOntology(&rdf.RDFOntology{Package: "rdf"}) mustAddOntology(&rdfs.RDFSchemaOntology{}) mustAddOntology(&schema.SchemaOntology{}) + mustAddOntology(&rfc.RFCOntology{Package: "rfc"}) } var ( diff --git a/tools/exp/rdf/rfc/ontology.go b/tools/exp/rdf/rfc/ontology.go new file mode 100644 index 0000000..e4aed1c --- /dev/null +++ b/tools/exp/rdf/rfc/ontology.go @@ -0,0 +1,148 @@ +// Package RFC contains ontology values that are defined in RFCs, BCPs, and +// other miscellaneous standards. +package rfc + +import ( + "fmt" + "github.com/cjslep/activity/tools/exp/codegen" + "github.com/cjslep/activity/tools/exp/rdf" + "github.com/dave/jennifer/jen" + "net/url" + "strings" +) + +const ( + rfcSpec = "https://tools.ietf.org/html/" + bcp47Spec = "bcp47" +) + +type RFCOntology struct { + Package string +} + +func (o *RFCOntology) SpecURI() string { + return rfcSpec +} + +func (o *RFCOntology) Load() ([]rdf.RDFNode, error) { + return o.LoadAsAlias("") +} + +func (o *RFCOntology) LoadAsAlias(s string) ([]rdf.RDFNode, error) { + return []rdf.RDFNode{ + &rdf.AliasedDelegate{ + Spec: rfcSpec, + Alias: s, + Name: bcp47Spec, + Delegate: &bcp47{pkg: o.Package}, + }, + }, nil +} + +func (o *RFCOntology) LoadSpecificAsAlias(alias, name string) ([]rdf.RDFNode, error) { + switch name { + case bcp47Spec: + return []rdf.RDFNode{ + &rdf.AliasedDelegate{ + Spec: "", + Alias: "", + Name: alias, + Delegate: &bcp47{pkg: o.Package}, + }, + }, nil + } + return nil, fmt.Errorf("rfc ontology cannot find %q to alias to %q", name, alias) +} + +func (o *RFCOntology) LoadElement(name string, payload map[string]interface{}) ([]rdf.RDFNode, error) { + return nil, nil +} + +func (o *RFCOntology) GetByName(name string) (rdf.RDFNode, error) { + name = strings.TrimPrefix(name, o.SpecURI()) + switch name { + case bcp47Spec: + return &bcp47{pkg: o.Package}, nil + } + return nil, fmt.Errorf("rfc ontology could not find node for name %s", name) +} + +var _ rdf.RDFNode = &bcp47{} + +type bcp47 struct { + pkg string +} + +func (b *bcp47) Enter(key string, ctx *rdf.ParsingContext) (bool, error) { + return true, fmt.Errorf("bcp47 langaugetag cannot be entered") +} + +func (b *bcp47) Exit(key string, ctx *rdf.ParsingContext) (bool, error) { + return true, fmt.Errorf("bcp47 languagetag cannot be exited") +} + +func (b *bcp47) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) { + v := ctx.Result.GetReference(rfcSpec) + if len(v.Values[bcp47Spec].Name) == 0 { + u, err := url.Parse(rfcSpec + bcp47Spec) + if err != nil { + return true, err + } + val := &rdf.VocabularyValue{ + Name: bcp47Spec, + URI: u, + DefinitionType: jen.String(), + Zero: "\"\"", + IsNilable: false, + SerializeFn: rdf.SerializeValueFunction( + b.pkg, + bcp47Spec, + jen.String(), + []jen.Code{ + jen.Return( + jen.Id(codegen.This()), + jen.Nil(), + ), + }), + DeserializeFn: rdf.DeserializeValueFunction( + b.pkg, + bcp47Spec, + jen.String(), + []jen.Code{ + jen.If( + jen.List( + jen.Id("s"), + jen.Id("ok"), + ).Op(":=").Id(codegen.This()).Assert(jen.String()), + jen.Id("ok"), + ).Block( + jen.Return( + jen.Id("s"), + jen.Nil(), + ), + ).Else().Block( + jen.Return( + jen.Lit(""), + jen.Qual("fmt", "Errorf").Call( + jen.Lit("%v cannot be interpreted as a string for bcp47 languagetag"), + jen.Id(codegen.This()), + ), + ), + ), + }), + LessFn: rdf.LessFunction( + b.pkg, + bcp47Spec, + jen.String(), + []jen.Code{ + jen.Return( + jen.Id("lhs").Op("<").Id("rhs"), + ), + }), + } + if err = v.SetValue(bcp47Spec, val); err != nil { + return true, err + } + } + return true, nil +} diff --git a/tools/exp/spec.json b/tools/exp/spec.json index d4e2d5f..ea6439d 100644 --- a/tools/exp/spec.json +++ b/tools/exp/spec.json @@ -4,6 +4,7 @@ "owl": "http://www.w3.org/2002/07/owl#", "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "rfc": "https://tools.ietf.org/html/", "schema": "http://schema.org/", "xsd": "http://www.w3.org/2001/XMLSchema#" }, @@ -4021,7 +4022,7 @@ "isDefinedBy": "https://www.w3.org/TR/activitystreams-vocabulary/#dfn-hreflang", "range": { "type": "owl:Class", - "unionOf": [] + "unionOf": "rfc:bcp47" }, "name": "hreflang", "url": "https://www.w3.org/TR/activitystreams-vocabulary/#dfn-hreflang"