use crate::codegen::ir::namespace::Namespace;
use crate::codegen::ir::ty::enumeration::IrTypeEnumRef;
use crate::codegen::ir::ty::general_list::IrTypeGeneralList;
use crate::codegen::ir::ty::primitive::IrTypePrimitive;
use crate::codegen::ir::ty::primitive_list::IrTypePrimitiveList;
use crate::codegen::ir::ty::{IrContext, IrType, IrTypeTrait};
crate::ir! {
pub enum IrTypeDelegate {
Array(IrTypeDelegateArray),
String,
PrimitiveEnum(IrTypeDelegatePrimitiveEnum),
Time(IrTypeDelegateTime),
Uuid,
Backtrace,
AnyhowException,
}
pub struct IrTypeDelegateArray {
pub namespace: Namespace,
pub length: usize,
pub mode: IrTypeDelegateArrayMode,
}
pub enum IrTypeDelegateArrayMode {
General(Box<IrType>),
Primitive(IrTypePrimitive),
}
pub struct IrTypeDelegatePrimitiveEnum {
pub(crate) ir: IrTypeEnumRef,
pub(crate) repr: IrTypePrimitive,
}
#[derive(Copy, strum_macros::Display)]
pub enum IrTypeDelegateTime {
Local,
Utc,
Naive,
Duration,
}
}
impl IrTypeTrait for IrTypeDelegate {
fn visit_children_types<F: FnMut(&IrType) -> bool>(
&self,
f: &mut F,
ir_context: &impl IrContext,
) {
self.get_delegate().visit_types(f, ir_context);
}
fn safe_ident(&self) -> String {
match self {
IrTypeDelegate::Array(array) => array.safe_ident(),
IrTypeDelegate::String => "String".to_owned(),
IrTypeDelegate::PrimitiveEnum(ir) => ir.ir.safe_ident(),
IrTypeDelegate::Time(ir) => format!("Chrono_{}", ir),
IrTypeDelegate::Uuid => "Uuid".to_owned(),
IrTypeDelegate::Backtrace => "Backtrace".to_owned(),
IrTypeDelegate::AnyhowException => "AnyhowException".to_owned(),
}
}
fn rust_api_type(&self) -> String {
match self {
IrTypeDelegate::Array(array) => {
format!("[{}; {}]", array.inner().rust_api_type(), array.length)
}
IrTypeDelegate::String => "String".to_owned(),
IrTypeDelegate::PrimitiveEnum(IrTypeDelegatePrimitiveEnum { ir, .. }) => {
ir.rust_api_type()
}
IrTypeDelegate::Time(ir) => match ir {
IrTypeDelegateTime::Naive => "chrono::NaiveDateTime",
IrTypeDelegateTime::Local => "chrono::DateTime::<chrono::Local>",
IrTypeDelegateTime::Utc => "chrono::DateTime::<chrono::Utc>",
IrTypeDelegateTime::Duration => "chrono::Duration",
}
.to_owned(),
IrTypeDelegate::Uuid => "uuid::Uuid".to_owned(),
IrTypeDelegate::Backtrace => "backtrace::Backtrace".to_owned(),
IrTypeDelegate::AnyhowException => "anyhow::Error".to_owned(),
}
}
fn as_primitive(&self) -> Option<&IrTypePrimitive> {
match self {
IrTypeDelegate::PrimitiveEnum(IrTypeDelegatePrimitiveEnum { repr, .. }) => Some(repr),
IrTypeDelegate::Time(_) => Some(&IrTypePrimitive::I64),
_ => None,
}
}
fn self_namespace(&self) -> Option<Namespace> {
match self {
IrTypeDelegate::PrimitiveEnum(inner) => inner.ir.self_namespace(),
IrTypeDelegate::Array(inner) => Some(inner.namespace.clone()),
_ => None,
}
}
}
impl IrTypeDelegate {
pub fn get_delegate(&self) -> IrType {
match self {
IrTypeDelegate::Array(array) => array.get_delegate(),
IrTypeDelegate::String => IrType::PrimitiveList(IrTypePrimitiveList {
primitive: IrTypePrimitive::U8,
}),
IrTypeDelegate::PrimitiveEnum(inner) => IrType::Primitive(inner.repr.clone()),
IrTypeDelegate::Time(_) => IrType::Primitive(IrTypePrimitive::I64),
IrTypeDelegate::Uuid => IrType::PrimitiveList(IrTypePrimitiveList {
primitive: IrTypePrimitive::U8,
}),
IrTypeDelegate::Backtrace => IrType::Delegate(IrTypeDelegate::String),
IrTypeDelegate::AnyhowException => IrType::Delegate(IrTypeDelegate::String),
}
}
}
impl IrTypeDelegateArray {
pub fn get_delegate(&self) -> IrType {
match &self.mode {
IrTypeDelegateArrayMode::General(general) => IrType::GeneralList(IrTypeGeneralList {
inner: general.clone(),
}),
IrTypeDelegateArrayMode::Primitive(primitive) => {
IrType::PrimitiveList(IrTypePrimitiveList {
primitive: primitive.clone(),
})
}
}
}
pub fn inner(&self) -> IrType {
match &self.mode {
IrTypeDelegateArrayMode::General(general) => *general.clone(),
IrTypeDelegateArrayMode::Primitive(primitive) => IrType::Primitive(primitive.clone()),
}
}
pub fn safe_ident(&self) -> String {
let length = &self.length;
match &self.mode {
IrTypeDelegateArrayMode::General(general) => {
format!("{}_array_{length}", general.safe_ident())
}
IrTypeDelegateArrayMode::Primitive(primitive) => {
format!("{}_array_{length}", primitive.safe_ident())
}
}
}
}