use proc_macro2::TokenStream;
use quote::quote;
use crate::emit::{type_path, type_var_ident};
use crate::ir::{DamlType, TypeRef};
#[must_use]
pub(crate) fn rust_type(ty: &DamlType) -> TokenStream {
match ty {
DamlType::Unit => quote!(rt::Unit),
DamlType::Bool => quote!(bool),
DamlType::Int64 => quote!(rt::Int64),
DamlType::Numeric(_) => quote!(rt::Numeric),
DamlType::Text => quote!(::std::string::String),
DamlType::Timestamp => quote!(rt::Timestamp),
DamlType::Date => quote!(rt::Date),
DamlType::Party => quote!(rt::Party),
DamlType::ContractId(inner) => {
let inner = rust_type(inner);
quote!(rt::ContractId<#inner>)
}
DamlType::List(inner) => {
let inner = rust_type(inner);
quote!(::std::vec::Vec<#inner>)
}
DamlType::Optional(inner) => {
let inner = nested_optional_inner(inner);
quote!(::core::option::Option<#inner>)
}
DamlType::TextMap(inner) => {
let inner = rust_type(inner);
quote!(rt::TextMap<#inner>)
}
DamlType::GenMap(key, value) => {
let key = rust_type(key);
let value = rust_type(value);
quote!(rt::GenMap<#key, #value>)
}
DamlType::Ref(reference) => rust_ref(reference),
DamlType::Var(name) => {
let ident = type_var_ident(name);
quote!(#ident)
}
DamlType::Boxed(inner) => {
let inner = rust_type(inner);
quote!(::std::boxed::Box<#inner>)
}
}
}
fn nested_optional_inner(ty: &DamlType) -> TokenStream {
match ty {
DamlType::Optional(inner) => {
let inner = nested_optional_inner(inner);
quote!(rt::NestedOpt<#inner>)
}
other => rust_type(other),
}
}
fn rust_ref(reference: &TypeRef) -> TokenStream {
let path = type_path(&reference.path);
if reference.args.is_empty() {
path
} else {
let args = reference.args.iter().map(rust_type);
quote!(#path<#(#args),*>)
}
}