diff --git a/lib/rdf/xsd/datatypes/string.ex b/lib/rdf/xsd/datatypes/string.ex index 4b42ef6..d828cab 100644 --- a/lib/rdf/xsd/datatypes/string.ex +++ b/lib/rdf/xsd/datatypes/string.ex @@ -9,6 +9,25 @@ defmodule RDF.XSD.String do name: "string", id: RDF.Utils.Bootstrapping.xsd_iri("string") + def_applicable_facet RDF.XSD.Facets.MinLength + def_applicable_facet RDF.XSD.Facets.MaxLength + def_applicable_facet RDF.XSD.Facets.Length + + @doc false + def min_length_conform?(min_length, value, _lexical) do + String.length(value) >= min_length + end + + @doc false + def max_length_conform?(max_length, value, _lexical) do + String.length(value) <= max_length + end + + @doc false + def length_conform?(length, value, _lexical) do + String.length(value) == length + end + @impl RDF.XSD.Datatype @spec lexical_mapping(String.t(), Keyword.t()) :: valid_value def lexical_mapping(lexical, _), do: to_string(lexical) diff --git a/lib/rdf/xsd/facets/length.ex b/lib/rdf/xsd/facets/length.ex new file mode 100644 index 0000000..4bc552f --- /dev/null +++ b/lib/rdf/xsd/facets/length.ex @@ -0,0 +1,3 @@ +defmodule RDF.XSD.Facets.Length do + use RDF.XSD.Facet, name: :length, type: integer +end diff --git a/lib/rdf/xsd/facets/max_length.ex b/lib/rdf/xsd/facets/max_length.ex new file mode 100644 index 0000000..8a8ccce --- /dev/null +++ b/lib/rdf/xsd/facets/max_length.ex @@ -0,0 +1,3 @@ +defmodule RDF.XSD.Facets.MaxLength do + use RDF.XSD.Facet, name: :max_length, type: integer +end diff --git a/lib/rdf/xsd/facets/min_length.ex b/lib/rdf/xsd/facets/min_length.ex new file mode 100644 index 0000000..6163129 --- /dev/null +++ b/lib/rdf/xsd/facets/min_length.ex @@ -0,0 +1,3 @@ +defmodule RDF.XSD.Facets.MinLength do + use RDF.XSD.Facet, name: :min_length, type: integer +end diff --git a/test/support/test_datatypes.ex b/test/support/test_datatypes.ex index 9c50ca5..84af7da 100644 --- a/test/support/test_datatypes.ex +++ b/test/support/test_datatypes.ex @@ -1,4 +1,13 @@ defmodule RDF.TestDatatypes do + defmodule Initials do + use RDF.XSD.Datatype.Restriction, + name: "initials", + id: "http://example.com/initials", + base: RDF.XSD.String + + def_facet_constraint RDF.XSD.Facets.Length, 2 + end + defmodule Age do use RDF.XSD.Datatype.Restriction, name: "age", diff --git a/test/unit/xsd/datatypes/string_test.exs b/test/unit/xsd/datatypes/string_test.exs index 8e16d42..e60ecbc 100644 --- a/test/unit/xsd/datatypes/string_test.exs +++ b/test/unit/xsd/datatypes/string_test.exs @@ -3,6 +3,16 @@ defmodule RDF.XSD.StringTest do datatype: RDF.XSD.String, name: "string", primitive: true, + applicable_facets: [ + RDF.XSD.Facets.MinLength, + RDF.XSD.Facets.MaxLength, + RDF.XSD.Facets.Length, + ], + facets: %{ + max_length: nil, + min_length: nil, + length: nil + }, valid: %{ # input => { value, lexical, canonicalized } "foo" => {"foo", nil, "foo"},