///|
/// The module of the embedded runtime, relative to the generated package.
let runtime_module : String = "._runtime"
///|
/// The module of the generated data types.
let models_module : String = ".models"
///|
/// The module of the generated modeled errors.
let errors_module : String = ".errors"
///|
/// The Python type of a shape value, as a Pydantic field annotation.
priv enum Ty {
Str
Boolean
/// An integer type of the runtime: Byte, Short, Integer, Long or BigInteger.
IntOf(String)
Floating
BigDec
Blob
Doc
Time(String)
/// A generated class or type alias, and its module.
Named(String, String)
ListOf(Ty)
MapOf(Ty)
Opt(Ty)
UnitT
} derive(Eq, Debug)
///|
/// The wrappers of a type, outer first, and the leaf type inside them. The
/// walk keeps its own state, so a deep type does not recurse.
fn Ty::layers(self : Ty) -> (Array[Ty], Ty) {
let wrappers : Array[Ty] = []
let mut ty = self
for ;; {
match ty {
ListOf(inner) | MapOf(inner) | Opt(inner) => {
wrappers.push(ty)
ty = inner
}
leaf => break (wrappers, leaf)
}
}
}
///|
/// The module and the name that a leaf type imports, if any.
fn Ty::leaf_import(self : Ty) -> (String, String)? {
match self {
Str => None
Boolean => Some(("pydantic", "StrictBool"))
IntOf(name) => Some((runtime_module, name))
Floating => Some((runtime_module, "Double"))
BigDec => Some((runtime_module, "BigDecimal"))
Blob => Some((runtime_module, "Blob"))
Doc => Some((runtime_module, "Document"))
Time(name) => Some((runtime_module, name))
Named(name, module_) => Some((module_, name))
UnitT => Some((runtime_module, "Unit"))
ListOf(_) | MapOf(_) | Opt(_) => None
}
}
///|
fn Ty::leaf_text(self : Ty) -> String {
match self {
Str => "str"
ListOf(_) | MapOf(_) | Opt(_) => ""
leaf =>
match leaf.leaf_import() {
Some((_, name)) => name
None => ""
}
}
}
///|
/// The annotation text of the type.
fn Ty::text(self : Ty) -> String {
let (wrappers, leaf) = self.layers()
let mut text = leaf.leaf_text()
for index = wrappers.length() - 1; index >= 0; index = index - 1 {
text = match wrappers[index] {
ListOf(_) => "list[\{text}]"
MapOf(_) => "dict[str, \{text}]"
_ => "\{text} | None"
}
}
text
}
///|
/// The import that the annotation of the type needs, if any.
fn Ty::import_of(self : Ty) -> (String, String)? {
let (_, leaf) = self.layers()
leaf.leaf_import()
}
///|
let unit_id : @smithy.ShapeId = @smithy.ShapeId::parse("smithy.api#Unit").unwrap()
///|
/// The timestamp annotation of each format.
fn timestamp_name(format : String) -> String {
match format {
"date-time" => "DateTimeTimestamp"
"http-date" => "HttpDateTimestamp"
_ => "EpochSecondsTimestamp"
}
}
///|
fn prelude_ty(name : String, format : String) -> Ty? {
match name {
"String" => Some(Str)
"Boolean" | "PrimitiveBoolean" => Some(Boolean)
"Byte" | "PrimitiveByte" => Some(IntOf("Byte"))
"Short" | "PrimitiveShort" => Some(IntOf("Short"))
"Integer" | "PrimitiveInteger" => Some(IntOf("Integer"))
"Long" | "PrimitiveLong" => Some(IntOf("Long"))
"BigInteger" => Some(IntOf("BigInteger"))
"Float" | "PrimitiveFloat" | "Double" | "PrimitiveDouble" => Some(Floating)
"BigDecimal" => Some(BigDec)
"Blob" => Some(Blob)
"Document" => Some(Doc)
"Timestamp" => Some(Time(timestamp_name(format)))
"Unit" => Some(UnitT)
_ => None
}
}
///|
fn simple_ty(simple : @smithy.SimpleType, format : String) -> Ty {
match simple {
String => Str
Boolean => Boolean
Byte => IntOf("Byte")
Short => IntOf("Short")
Integer => IntOf("Integer")
Long => IntOf("Long")
BigInteger => IntOf("BigInteger")
Float | Double => Floating
BigDecimal => BigDec
Blob => Blob
Document => Doc
Timestamp => Time(timestamp_name(format))
}
}