teo-generator 0.3.9

SDK generators for Teo
Documentation
use teo_parser::r#type::synthesized_shape_reference::{SynthesizedShapeReference, SynthesizedShapeReferenceKind};
use teo_result::{Error, Result};
use teo_parser::r#type::Type;
use crate::outline::outline::Mode;
use crate::utils::declared_shape_lookup::declared_shape_lookup;
use crate::utils::enum_reference_lookup::enum_reference_lookup;
use crate::utils::shape_reference_lookup::shape_reference_lookup;

pub(crate) fn lookup(t: &Type, ts_result_mode: bool, mode: Mode) -> Result<String> {
    Ok(match t {
        Type::Undetermined => Err(Error::new("encountered undetermined"))?,
        Type::Ignored => Err(Error::new("encountered ignored"))?,
        Type::Any => "any".to_owned(),
        Type::Null => "null".to_owned(),
        Type::Bool => "boolean".to_owned(),
        Type::Int => "number".to_owned(),
        Type::Int64 => "number".to_owned(),
        Type::Float32 => "number".to_owned(),
        Type::Float => "number".to_owned(),
        Type::Decimal => "Decimal".to_owned(),
        Type::String => "string".to_owned(),
        Type::ObjectId => if mode.is_client() { "string".to_owned() } else { "ObjectId".to_owned() },
        Type::Date => if mode.is_client() { "string".to_owned() } else { "DateOnly".to_owned() },
        Type::DateTime => "Date".to_owned(),
        Type::File => "File".to_owned(),
        Type::Regex => Err(Error::new("encountered regex"))?,
        Type::Model => Err(Error::new("encountered model"))?,
        Type::DataSet => Err(Error::new("encountered dataset"))?,
        Type::Enumerable(inner) => format!("Enumerable<{}>", lookup(inner.as_ref(), ts_result_mode, mode)?),
        Type::Array(inner) => if ts_result_mode {
            if let Some(shape_reference) = inner.as_synthesized_shape_reference() {
                format!("{}[]", ts_result_shape_reference_lookup(shape_reference)?)
            } else if inner.is_union() {
                format!("({})[]", lookup(inner.as_ref(), ts_result_mode, mode)?)
            } else {
                format!("{}[]", lookup(inner.as_ref(), ts_result_mode, mode)?)
            }
        } else {
            if inner.is_union() {
                format!("({})[]", lookup(inner.as_ref(), ts_result_mode, mode)?)
            } else {
                format!("{}[]", lookup(inner.as_ref(), ts_result_mode, mode)?)
            }
        },
        Type::Dictionary(inner) => format!("{{[key: string]: {}}}", lookup(inner.as_ref(), ts_result_mode, mode)?),
        Type::Tuple(t) => format!("[{}]", t.iter().map(|t| lookup(t, ts_result_mode, mode)).collect::<Result<Vec<String>>>()?.join(", ")),
        Type::Range(_) => "Range".to_owned(),
        Type::Union(types) => types.iter().map(|t| Ok(lookup(t, ts_result_mode, mode)?)).collect::<Result<Vec<String>>>()?.join(" | "),
        Type::EnumVariant(reference) => reference.string_path().join("."),
        Type::InterfaceObject(reference, types) => if types.is_empty() {
            reference.string_path().join(".")
        } else {
            reference.string_path().join(".") + "<" + &types.iter().map(|t| lookup(t, ts_result_mode, mode)).collect::<Result<Vec<String>>>()?.join(", ") + ">"
        },
        Type::ModelObject(reference) => reference.string_path().join("."),
        Type::GenericItem(i) => i.to_owned(),
        Type::Optional(inner) => if ts_result_mode {
            if let Some(shape_reference) = inner.as_synthesized_shape_reference() {
                ts_result_shape_reference_lookup(shape_reference)?
            } else {
                format!("{}?", lookup(inner.as_ref(), ts_result_mode, mode)?)
            }
        } else {
            format!("{}?", lookup(inner.as_ref(), ts_result_mode, mode)?)
        },
        Type::SynthesizedShapeReference(shape_reference) => if ts_result_mode {
            ts_result_shape_reference_lookup(shape_reference)?
        } else {
            shape_reference_lookup(shape_reference, ".", Mode::Client)?
        },
        Type::SynthesizedEnumReference(enum_reference) => enum_reference_lookup(enum_reference, ".")?,
        Type::DeclaredSynthesizedShape(reference, model_type) => declared_shape_lookup(reference, model_type.as_ref(), ".")?,
        _ => Err(Error::new("encountered unhandled type in lookup"))?,
    })
}

pub(crate) fn ts_result_shape_reference_lookup(shape_reference: &SynthesizedShapeReference) -> Result<String> {
    Ok(match shape_reference.kind {
        SynthesizedShapeReferenceKind::Result => {
            let base = shape_reference.owner.as_model_object().unwrap().string_path().join(".");
            format!("CheckSelectInclude<T, {base}, {base}GetPayload<T>>")
        },
        SynthesizedShapeReferenceKind::CountAggregateResult => format!("{}CountAggregateResult", shape_reference.owner.as_model_object().unwrap().string_path().join(".")),
        SynthesizedShapeReferenceKind::SumAggregateResult => format!("{}SumAggregateResult", shape_reference.owner.as_model_object().unwrap().string_path().join(".")),
        SynthesizedShapeReferenceKind::AvgAggregateResult => format!("{}AvgAggregateResult", shape_reference.owner.as_model_object().unwrap().string_path().join(".")),
        SynthesizedShapeReferenceKind::MinAggregateResult => format!("{}MinAggregateResult", shape_reference.owner.as_model_object().unwrap().string_path().join(".")),
        SynthesizedShapeReferenceKind::MaxAggregateResult => format!("{}MaxAggregateResult", shape_reference.owner.as_model_object().unwrap().string_path().join(".")),
        SynthesizedShapeReferenceKind::AggregateResult => {
            let base = shape_reference.owner.as_model_object().unwrap().string_path().join(".");
            format!("Get{base}AggregateType<T>")
        },
        SynthesizedShapeReferenceKind::GroupByResult => {
            let base = shape_reference.owner.as_model_object().unwrap().string_path().join(".");
            format!("{{}} extends InputErrors ? Get{base}GroupByPayload<T> : InputErrors")
        },
        _ => shape_reference_lookup(shape_reference, ".", Mode::Client)?,
    })
}