annotation URI::Params::Serializable::Scalar
Overview
Annotate a type to mark it as a scalar, so a single string query value will be tried to cast.
For example, Int32
is scalar by default, thus in case "foo=42"
, "42"
is tried to cast to Int32
.
Good candidates to become scalar: URI
and Time
; for example:
@[HTTP::Params::Serializable::Scalar]
class URI
def to_http_param(builder : HTTP::Params::Builder, key : String)
builder.add(key, to_s)
end
def self.from_http_param(value : String)
return URI.parse(value)
end
end
struct MyParams
include HTTP::Params::Serializable
getter uri : URI
end
params = MyParams.from_query("uri=https://example.com")
pp params.uri # => <URI @host="example.com" ...>
URI
and Time::EpochConverter
extensions are shipped by default:
require "http-params-parseable"
require "http-params-parseable/ext/uri"
require "http-params-parseable/ext/time/epoch_converter"
struct MyParams
include HTTP::Params::Serializable
getter uri : URI
@[HTTP::Param(converter: Time::EpochConverter)]
getter time : Time
end
If you have annotated a type as scalar, then it must implement these methods:
def to_http_param(builder : HTTP::Params::Builder, key : String)
# E.g. builder.add(key, self.to_s)
end
def self.from_http_param(value : String) : self
# E.g. value.to_s
end
Otherwise (if the type is not Scalar
), the methods become a little more complex:
def to_http_param(builder : HTTP::Params::Builder, key : String? = nil)
# Notice the *key* is nilable
end
# Or if you're using a converter on a param:
def to_http_param(builder : HTTP::Params::Builder, key : String? = nil, converter : C = nil) forall C
# ditto
end
def self.from_http_param(query : String, path : Tuple) : self
# Notice the *path* argument
end
# Or if you're using a converter on a param:
def self.from_http_param(query : String, path : Tuple, converter : C = nil) : self forall C
# ditto
end