///|
pub struct Config {
service : ServiceId
version : OpenRpcVersion
protocol_version : @rpc.ProtocolVersion
member_names : @validation.MemberNames
timestamp_format : @validation.TimestampFormat
extensions : ExtensionPolicy
title : String?
api_version : String?
}
///|
pub fn Config::new(
service : ServiceId,
version~ : OpenRpcVersion = V1_3_2,
protocol_version~ : @rpc.ProtocolVersion = @rpc.V2_0,
member_names~ : @validation.MemberNames = @validation.Smithy,
timestamp_format~ : @validation.TimestampFormat = @validation.EpochSeconds,
extensions~ : ExtensionPolicy = Preserve,
title~ : String? = None,
api_version~ : String? = None,
) -> Config {
{
service,
version,
protocol_version,
member_names,
timestamp_format,
extensions,
title,
api_version,
}
}
///|
pub fn Config::service(self : Config) -> ServiceId {
self.service
}
///|
fn settings_string(
fields : Map[String, Json],
name : String,
id : @smithy.ShapeId,
) -> String? raise OpenRpcError {
match fields.get(name) {
None => None
Some(String(value)) => Some(value)
_ =>
raise InvalidConfiguration(
id,
"I expected a string for setting `" + name + "`.",
)
}
}
///|
pub fn Config::from_json(settings : Json) -> Config raise OpenRpcError {
let subject = @smithy.ShapeId::parse("smithy.rpc#jsonRpc").unwrap()
guard settings is Object(fields) else {
raise InvalidConfiguration(
subject, "I expected OpenRPC settings to be an object.",
)
}
guard settings_string(fields, "service", subject).bind(ServiceId::parse)
is Some(service) else {
raise InvalidConfiguration(
subject, "I expected a root service shape ID in setting `service`.",
)
}
let id = service.shape_id()
for key, _ in fields {
if ![
"service", "version", "protocolVersion", "useJsonName", "timestampFormat",
"extensions", "title", "apiVersion",
].contains(key) {
raise InvalidConfiguration(
id,
"I found unknown OpenRPC setting `" + key + "`.",
)
}
}
guard OpenRpcVersion::parse(
settings_string(fields, "version", id).unwrap_or("1.3.2"),
)
is Some(version) else {
raise InvalidConfiguration(id, "I support OpenRPC document version 1.3.2.")
}
guard settings_string(fields, "protocolVersion", id).unwrap_or("2.0") == "2.0" else {
raise InvalidConfiguration(
id, "I can export only JSON-RPC wire version 2.0 as OpenRPC.",
)
}
let member_names = match fields.get("useJsonName") {
None | Some(False) => @validation.Smithy
Some(True) => @validation.JsonName
_ =>
raise InvalidConfiguration(
id, "I expected a boolean useJsonName setting.",
)
}
let timestamp_format = match
settings_string(fields, "timestampFormat", id).unwrap_or("epoch-seconds") {
"epoch-seconds" => @validation.EpochSeconds
"date-time" => @validation.DateTime
_ =>
raise InvalidConfiguration(
id, "I expected epoch-seconds or date-time for timestampFormat.",
)
}
let extensions = match
settings_string(fields, "extensions", id).unwrap_or("preserve") {
"preserve" => Preserve
"omit" => Omit
"fail" => Fail
_ =>
raise InvalidConfiguration(
id, "I expected preserve, omit or fail for extensions.",
)
}
Config::new(
service,
version~,
member_names~,
timestamp_format~,
extensions~,
title=settings_string(fields, "title", id),
api_version=settings_string(fields, "apiVersion", id),
)
}