Merge pull request #9 from pukkamustard/base64Binary
Add XSD.Base64Binary
This commit is contained in:
commit
be87736e60
5 changed files with 131 additions and 3 deletions
|
@ -36,7 +36,8 @@ defmodule RDF.Literal.Datatype.Registry do
|
|||
XSD.Date,
|
||||
XSD.Time,
|
||||
XSD.DateTime,
|
||||
XSD.AnyURI
|
||||
XSD.AnyURI,
|
||||
XSD.Base64Binary
|
||||
] ++ @builtin_numeric_datatypes
|
||||
|
||||
@builtin_datatypes [RDF.LangString | @builtin_xsd_datatypes]
|
||||
|
|
|
@ -52,7 +52,7 @@ defmodule RDF.XSD.Datatype do
|
|||
| `xsd:gMonthDay` | ❌ |
|
||||
| `xsd:gDay` | ❌ |
|
||||
| `xsd:gMonth` | ❌ |
|
||||
| `xsd:base64Binary` | ❌ |
|
||||
| `xsd:base64Binary` | `RDF.XSD.Base64Binary` |
|
||||
| `xsd:hexBinary` | ❌ |
|
||||
| `xsd:anyURI` | `RDF.XSD.AnyURI` |
|
||||
| `xsd:QName` | ❌ |
|
||||
|
|
64
lib/rdf/xsd/datatypes/base64_binary.ex
Normal file
64
lib/rdf/xsd/datatypes/base64_binary.ex
Normal file
|
@ -0,0 +1,64 @@
|
|||
defmodule RDF.XSD.Base64Binary do
|
||||
@moduledoc """
|
||||
`RDF.XSD.Datatype` for XSD base64Binary.
|
||||
"""
|
||||
|
||||
@type valid_value :: binary()
|
||||
|
||||
use RDF.XSD.Datatype.Primitive,
|
||||
name: "base64Binary",
|
||||
id: RDF.Utils.Bootstrapping.xsd_iri("base64Binary")
|
||||
|
||||
alias RDF.XSD
|
||||
|
||||
def_applicable_facet XSD.Facets.MinLength
|
||||
def_applicable_facet XSD.Facets.MaxLength
|
||||
def_applicable_facet XSD.Facets.Length
|
||||
def_applicable_facet XSD.Facets.Pattern
|
||||
|
||||
@doc false
|
||||
def min_length_conform?(min_length, value, _lexical) do
|
||||
byte_size(value) >= min_length
|
||||
end
|
||||
|
||||
@doc false
|
||||
def max_length_conform?(max_length, value, _lexical) do
|
||||
byte_size(value) <= max_length
|
||||
end
|
||||
|
||||
@doc false
|
||||
def length_conform?(length, value, _lexical) do
|
||||
byte_size(value) == length
|
||||
end
|
||||
|
||||
@doc false
|
||||
def pattern_conform?(pattern, value, _lexical) do
|
||||
XSD.Facets.Pattern.conform?(pattern, value)
|
||||
end
|
||||
|
||||
@impl XSD.Datatype
|
||||
@spec lexical_mapping(String.t(), Keyword.t()) :: valid_value()
|
||||
def lexical_mapping(lexical, _) do
|
||||
case Base.decode64(lexical) do
|
||||
{:ok, value} ->
|
||||
value
|
||||
|
||||
_ ->
|
||||
@invalid_value
|
||||
end
|
||||
end
|
||||
|
||||
@impl XSD.Datatype
|
||||
@spec elixir_mapping(any, Keyword.t()) :: nil | valid_value()
|
||||
def elixir_mapping(value, _) when is_binary(value), do: value
|
||||
def elixir_mapping(_, _), do: @invalid_value
|
||||
|
||||
@impl XSD.Datatype
|
||||
@spec canonical_mapping(valid_value()) :: String.t()
|
||||
def canonical_mapping(value), do: Base.encode64(value)
|
||||
|
||||
@impl RDF.Literal.Datatype
|
||||
def do_cast(value)
|
||||
def do_cast(%XSD.String{} = xsd_string), do: new(xsd_string.value, as_value: true)
|
||||
def do_cast(literal), do: super(literal)
|
||||
end
|
|
@ -24,7 +24,6 @@ defmodule RDF.Literal.Datatype.RegistryTest do
|
|||
ENTITY
|
||||
yearMonthDuration
|
||||
IDREFS
|
||||
base64Binary
|
||||
token
|
||||
NCName
|
||||
NMTOKEN
|
||||
|
|
64
test/unit/xsd/datatypes/base64_binary_test.exs
Normal file
64
test/unit/xsd/datatypes/base64_binary_test.exs
Normal file
|
@ -0,0 +1,64 @@
|
|||
defmodule RDF.XSD.Base64BinaryTest do
|
||||
use RDF.XSD.Datatype.Test.Case,
|
||||
datatype: RDF.XSD.Base64Binary,
|
||||
name: "base64Binary",
|
||||
primitive: true,
|
||||
applicable_facets: [
|
||||
RDF.XSD.Facets.MinLength,
|
||||
RDF.XSD.Facets.MaxLength,
|
||||
RDF.XSD.Facets.Length,
|
||||
RDF.XSD.Facets.Pattern
|
||||
],
|
||||
facets: %{
|
||||
max_length: nil,
|
||||
min_length: nil,
|
||||
length: nil,
|
||||
pattern: nil
|
||||
},
|
||||
valid: %{
|
||||
# input => { value, lexical, canonicalized }
|
||||
# "foo" does not require any padding
|
||||
Base.encode64("foo") => {"foo", nil, Base.encode64("foo")},
|
||||
# "foob" does require padding
|
||||
Base.encode64("foob") => {"foob", nil, Base.encode64("foob")},
|
||||
Base.encode64(<<0::32>>) => {<<0::32>>, nil, Base.encode64(<<0::32>>)}
|
||||
},
|
||||
invalid: [
|
||||
"not a base64 encoded value",
|
||||
Base.encode64("foob", padding: false),
|
||||
0,
|
||||
42,
|
||||
3.14,
|
||||
true,
|
||||
false
|
||||
]
|
||||
|
||||
describe "new/2" do
|
||||
test "interpret string as value" do
|
||||
assert XSD.base64Binary("foo", as_value: true) == XSD.base64Binary(Base.encode64("foo"))
|
||||
end
|
||||
|
||||
test "interpret string as value even if string is correctly encodded Base64" do
|
||||
assert XSD.base64Binary(Base.encode64("foo"), as_value: true) ==
|
||||
XSD.base64Binary(Base.encode64(Base.encode64("foo")))
|
||||
end
|
||||
end
|
||||
|
||||
describe "cast/1" do
|
||||
test "casting a base64Binary returns the input as is" do
|
||||
assert XSD.base64Binary("foo", as_value: true) |> XSD.Base64Binary.cast() ==
|
||||
XSD.base64Binary("foo", as_value: true)
|
||||
end
|
||||
|
||||
test "casting a string" do
|
||||
assert XSD.string("foo") |> XSD.Base64Binary.cast() ==
|
||||
XSD.base64Binary("foo", as_value: true)
|
||||
end
|
||||
|
||||
test "string value is interpret as value (even if valid Base64 encoded string)" do
|
||||
assert XSD.string(Base.encode64("Hello World!"))
|
||||
|> XSD.Base64Binary.cast() !==
|
||||
XSD.base64Binary("Hello World!", as_value: true)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue