Skip to content

Auto generated code

Matheus Dias de Souza edited this page May 2, 2024 · 5 revisions

It is easier to understand what SModel does by examining what it generates.

Given:

smodel! {
    mod smodel = crate;

    type Arena = Arena;

    /// My unified data type.
    struct Thingy {
        pub fn Thingy() {
            super();
        }

        /// Empty, Foo, FooBar or FooQux
        pub fn name(&self) -> String {
            "".into()
        }

        pub fn base_example(&self) -> String {
            "from base".into()
        }

        pub fn x(&self) -> f64 {
            0.0
        }
    }

    struct Foo: Thingy {
        pub fn Foo() {
            super();
        }

        #[inheritdoc]
        pub override fn name(&self) -> String {
            "Foo".into()
        }
    }

    struct FooBar: Foo {
        pub fn FooBar() {
            super();
        }

        #[inheritdoc]
        pub override fn name(&self) -> String {
            "FooBar".into()
        }

        pub override fn base_example(&self) -> String {
            format!("from bar; {}", super.base_example())
        }
    }
    
    struct FooBarBar: FooBar {
        let m_x: f64 = 0.0;
        let ref m_y: String = "".into();

        pub fn FooBarBar(x: f64, y: &str) {
            super();
            self.set_m_x(x);
            self.set_m_y(y.into());
        }

        #[inheritdoc]
        pub override fn name(&self) -> String {
            "FooBarBar".into()
        }

        pub override fn x(&self) -> f64 {
            self.m_x()
        }

        pub override fn base_example(&self) -> String {
            format!("from {}; {}", self.m_y(), super.base_example())
        }
    }

    struct FooQux: Foo {
        pub fn FooQux() {
            super();
        }

        #[inheritdoc]
        pub override fn name(&self) -> String {
            "FooQux".into()
        }
    }
}

It expands to:

// Recursive expansion of smodel! macro
// =====================================

pub type Arena = crate::Arena<__data__::__data_Thingy>;
#[doc = " My unified data type."]
#[derive(Clone)]
struct Thingy(::std::rc::Weak<__data__::__data_Thingy>);

impl PartialEq for Thingy {
    fn eq(&self, other: &Self) -> bool {
        self.0.ptr_eq(&other.0)
    }
}
impl ::std::hash::Hash for Thingy {
    fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
        self.0.as_ptr().hash(state)
    }
}
impl TryFrom<Thingy> for Foo {
    type Error = crate::SModelError;
    fn try_from(v: Thingy) -> Result<Self, Self::Error> {
        if let __data__::__variant_Thingy::__data_Foo(_o) = &v.0.upgrade().unwrap().__variant {
            Ok(Foo(Thingy(v.0.clone())))
        } else {
            Err(crate::SModelError::Contravariant)
        }
    }
}
impl TryFrom<Thingy> for FooBar {
    type Error = crate::SModelError;
    fn try_from(v: Thingy) -> Result<Self, Self::Error> {
        if let __data__::__variant_Thingy::__data_Foo(_o) = &v.0.upgrade().unwrap().__variant {
            if let __data__::__variant_Foo::__data_FooBar(_o) = &_o.__variant {
                Ok(FooBar(Foo(Thingy(v.0.clone()))))
            } else {
                Err(crate::SModelError::Contravariant)
            }
        } else {
            Err(crate::SModelError::Contravariant)
        }
    }
}
impl TryFrom<Thingy> for FooBarBar {
    type Error = crate::SModelError;
    fn try_from(v: Thingy) -> Result<Self, Self::Error> {
        if let __data__::__variant_Thingy::__data_Foo(_o) = &v.0.upgrade().unwrap().__variant {
            if let __data__::__variant_Foo::__data_FooBar(_o) = &_o.__variant {
                if let __data__::__variant_FooBar::__data_FooBarBar(_o) = &_o.__variant {
                    Ok(FooBarBar(FooBar(Foo(Thingy(v.0.clone())))))
                } else {
                    Err(crate::SModelError::Contravariant)
                }
            } else {
                Err(crate::SModelError::Contravariant)
            }
        } else {
            Err(crate::SModelError::Contravariant)
        }
    }
}
impl TryFrom<Thingy> for FooQux {
    type Error = crate::SModelError;
    fn try_from(v: Thingy) -> Result<Self, Self::Error> {
        if let __data__::__variant_Thingy::__data_Foo(_o) = &v.0.upgrade().unwrap().__variant {
            if let __data__::__variant_Foo::__data_FooQux(_o) = &_o.__variant {
                Ok(FooQux(Foo(Thingy(v.0.clone()))))
            } else {
                Err(crate::SModelError::Contravariant)
            }
        } else {
            Err(crate::SModelError::Contravariant)
        }
    }
}
#[derive(Clone, PartialEq, Hash)]
struct Foo(Thingy);

impl ::std::ops::Deref for Foo {
    type Target = Thingy;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}
impl From<Foo> for Thingy {
    fn from(v: Foo) -> Self {
        Thingy(v.0 .0.clone())
    }
}
impl TryFrom<Foo> for FooBar {
    type Error = crate::SModelError;
    fn try_from(v: Foo) -> Result<Self, Self::Error> {
        if let __data__::__variant_Thingy::__data_Foo(_o) = &v.0 .0.upgrade().unwrap().__variant
        {
            if let __data__::__variant_Foo::__data_FooBar(_o) = &_o.__variant {
                Ok(FooBar(Foo(Thingy(v.0 .0.clone()))))
            } else {
                Err(crate::SModelError::Contravariant)
            }
        } else {
            Err(crate::SModelError::Contravariant)
        }
    }
}
impl TryFrom<Foo> for FooBarBar {
    type Error = crate::SModelError;
    fn try_from(v: Foo) -> Result<Self, Self::Error> {
        if let __data__::__variant_Thingy::__data_Foo(_o) = &v.0 .0.upgrade().unwrap().__variant
        {
            if let __data__::__variant_Foo::__data_FooBar(_o) = &_o.__variant {
                if let __data__::__variant_FooBar::__data_FooBarBar(_o) = &_o.__variant {
                    Ok(FooBarBar(FooBar(Foo(Thingy(v.0 .0.clone())))))
                } else {
                    Err(crate::SModelError::Contravariant)
                }
            } else {
                Err(crate::SModelError::Contravariant)
            }
        } else {
            Err(crate::SModelError::Contravariant)
        }
    }
}
impl TryFrom<Foo> for FooQux {
    type Error = crate::SModelError;
    fn try_from(v: Foo) -> Result<Self, Self::Error> {
        if let __data__::__variant_Thingy::__data_Foo(_o) = &v.0 .0.upgrade().unwrap().__variant
        {
            if let __data__::__variant_Foo::__data_FooQux(_o) = &_o.__variant {
                Ok(FooQux(Foo(Thingy(v.0 .0.clone()))))
            } else {
                Err(crate::SModelError::Contravariant)
            }
        } else {
            Err(crate::SModelError::Contravariant)
        }
    }
}
#[derive(Clone, PartialEq, Hash)]
struct FooBar(Foo);

impl ::std::ops::Deref for FooBar {
    type Target = Foo;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}
impl From<FooBar> for Foo {
    fn from(v: FooBar) -> Self {
        Foo(v.0 .0.clone())
    }
}
impl From<FooBar> for Thingy {
    fn from(v: FooBar) -> Self {
        Thingy(v.0 .0 .0.clone())
    }
}
impl TryFrom<FooBar> for FooBarBar {
    type Error = crate::SModelError;
    fn try_from(v: FooBar) -> Result<Self, Self::Error> {
        if let __data__::__variant_Thingy::__data_Foo(_o) =
            &v.0 .0 .0.upgrade().unwrap().__variant
        {
            if let __data__::__variant_Foo::__data_FooBar(_o) = &_o.__variant {
                if let __data__::__variant_FooBar::__data_FooBarBar(_o) = &_o.__variant {
                    Ok(FooBarBar(FooBar(Foo(Thingy(v.0 .0 .0.clone())))))
                } else {
                    Err(crate::SModelError::Contravariant)
                }
            } else {
                Err(crate::SModelError::Contravariant)
            }
        } else {
            Err(crate::SModelError::Contravariant)
        }
    }
}
#[derive(Clone, PartialEq, Hash)]
struct FooBarBar(FooBar);

impl ::std::ops::Deref for FooBarBar {
    type Target = FooBar;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}
impl From<FooBarBar> for FooBar {
    fn from(v: FooBarBar) -> Self {
        FooBar(v.0 .0.clone())
    }
}
impl From<FooBarBar> for Foo {
    fn from(v: FooBarBar) -> Self {
        Foo(v.0 .0 .0.clone())
    }
}
impl From<FooBarBar> for Thingy {
    fn from(v: FooBarBar) -> Self {
        Thingy(v.0 .0 .0 .0.clone())
    }
}
#[derive(Clone, PartialEq, Hash)]
struct FooQux(Foo);

impl ::std::ops::Deref for FooQux {
    type Target = Foo;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}
impl From<FooQux> for Foo {
    fn from(v: FooQux) -> Self {
        Foo(v.0 .0.clone())
    }
}
impl From<FooQux> for Thingy {
    fn from(v: FooQux) -> Self {
        Thingy(v.0 .0 .0.clone())
    }
}
impl Thingy {
    fn __ctor(&self) {}

    pub fn new(arena: &Arena) -> Self {
        let __cto1 = Thingy(
            arena
                .allocate(__data__::__data_Thingy {
                    __variant: __data__::__variant_Thingy::__Nothing,
                })
                .clone(),
        );
        __cto1.__ctor();
        __cto1
    }
    fn __nd_name(&self) -> String {
        "".into()
    }
    fn __nd_base_example(&self) -> String {
        "from base".into()
    }
    fn __nd_x(&self) -> f64 {
        0.0
    }
    #[doc = " Empty, Foo, FooBar or FooQux"]
    pub fn name(&self) -> String {
        if self.is::<Foo>() {
            return Foo(self.clone()).name();
        }
        self.__nd_name()
    }
    pub fn base_example(&self) -> String {
        if self.is::<Foo>() {
            if self.is::<FooBar>() {
                return FooBar(Foo(self.clone())).base_example();
            }
        }
        self.__nd_base_example()
    }
    pub fn x(&self) -> f64 {
        if self.is::<Foo>() {
            if self.is::<FooBar>() {
                if self.is::<FooBarBar>() {
                    return FooBarBar(FooBar(Foo(self.clone()))).x();
                }
            }
        }
        self.__nd_x()
    }
    pub fn to<T: TryFrom<Thingy, Error = crate::SModelError>>(
        &self,
    ) -> Result<T, crate::SModelError> {
        T::try_from(self.clone())
    }
    pub fn is<T: TryFrom<Thingy, Error = crate::SModelError>>(&self) -> bool {
        T::try_from(self.clone()).is_ok()
    }
}
impl Foo {
    fn __ctor(&self) {}

    pub fn new(arena: &Arena) -> Self {
        let __cto1 = Foo(Thingy(
            arena
                .allocate(__data__::__data_Thingy {
                    __variant: __data__::__variant_Thingy::__data_Foo(::std::rc::Rc::new(
                        __data__::__data_Foo {
                            __variant: __data__::__variant_Foo::__Nothing,
                        },
                    )),
                })
                .clone(),
        ));
        Thingy::__ctor(&__cto1.0);
        __cto1.__ctor();
        __cto1
    }
    fn __nd_name(&self) -> String {
        "Foo".into()
    }
    #[doc = " Empty, Foo, FooBar or FooQux"]
    pub fn name(&self) -> String {
        if self.is::<FooBar>() {
            return FooBar(self.clone()).name();
        } else if self.is::<FooQux>() {
            return FooQux(self.clone()).name();
        }
        self.__nd_name()
    }
    pub fn to<T: TryFrom<Foo, Error = crate::SModelError>>(
        &self,
    ) -> Result<T, crate::SModelError> {
        T::try_from(self.clone())
    }
    pub fn is<T: TryFrom<Foo, Error = crate::SModelError>>(&self) -> bool {
        T::try_from(self.clone()).is_ok()
    }
}
impl FooBar {
    fn __ctor(&self) {}

    pub fn new(arena: &Arena) -> Self {
        let __cto1 = FooBar(Foo(Thingy(
            arena
                .allocate(__data__::__data_Thingy {
                    __variant: __data__::__variant_Thingy::__data_Foo(::std::rc::Rc::new(
                        __data__::__data_Foo {
                            __variant: __data__::__variant_Foo::__data_FooBar(
                                ::std::rc::Rc::new(__data__::__data_FooBar {
                                    __variant: __data__::__variant_FooBar::__Nothing,
                                }),
                            ),
                        },
                    )),
                })
                .clone(),
        )));
        Foo::__ctor(&__cto1.0);
        __cto1.__ctor();
        __cto1
    }
    fn __nd_name(&self) -> String {
        "FooBar".into()
    }
    fn __nd_base_example(&self) -> String {
        {
            let res = $crate::fmt::format(builtin #format_args(
                "from bar; {}",
                Thingy::__nd_base_example(&self.0 .0),
            ));
            res
        }
    }
    #[doc = " Empty, Foo, FooBar or FooQux"]
    pub fn name(&self) -> String {
        if self.is::<FooBarBar>() {
            return FooBarBar(self.clone()).name();
        }
        self.__nd_name()
    }
    pub fn base_example(&self) -> String {
        if self.is::<FooBarBar>() {
            return FooBarBar(self.clone()).base_example();
        }
        self.__nd_base_example()
    }
    pub fn to<T: TryFrom<FooBar, Error = crate::SModelError>>(
        &self,
    ) -> Result<T, crate::SModelError> {
        T::try_from(self.clone())
    }
    pub fn is<T: TryFrom<FooBar, Error = crate::SModelError>>(&self) -> bool {
        T::try_from(self.clone()).is_ok()
    }
}
impl FooBarBar {
    #[allow(non_snake_case)]
    fn m_x(&self) -> f64 {
        (if let __data__::__variant_Thingy::__data_Foo(o) =
            &self.0 .0 .0 .0.upgrade().unwrap().__variant
        {
            (if let __data__::__variant_Foo::__data_FooBar(o) = &o.__variant {
                (if let __data__::__variant_FooBar::__data_FooBarBar(o) = &o.__variant {
                    (&o.m_x)
                } else {
                    {
                        #[cold]
                        #[track_caller]
                        #[inline(never)]
                        const fn panic_cold_explicit() -> ! {
                            $crate::panicking::panic_explicit()
                        }
                        panic_cold_explicit();
                    }
                })
            } else {
                {
                    #[cold]
                    #[track_caller]
                    #[inline(never)]
                    const fn panic_cold_explicit() -> ! {
                        $crate::panicking::panic_explicit()
                    }
                    panic_cold_explicit();
                }
            })
        } else {
            {
                #[cold]
                #[track_caller]
                #[inline(never)]
                const fn panic_cold_explicit() -> ! {
                    $crate::panicking::panic_explicit()
                }
                panic_cold_explicit();
            }
        })
        .get()
    }
    #[allow(non_snake_case)]
    fn set_m_x(&self, v: f64) {
        (if let __data__::__variant_Thingy::__data_Foo(o) =
            &self.0 .0 .0 .0.upgrade().unwrap().__variant
        {
            (if let __data__::__variant_Foo::__data_FooBar(o) = &o.__variant {
                (if let __data__::__variant_FooBar::__data_FooBarBar(o) = &o.__variant {
                    (&o.m_x)
                } else {
                    {
                        #[cold]
                        #[track_caller]
                        #[inline(never)]
                        const fn panic_cold_explicit() -> ! {
                            $crate::panicking::panic_explicit()
                        }
                        panic_cold_explicit();
                    }
                })
            } else {
                {
                    #[cold]
                    #[track_caller]
                    #[inline(never)]
                    const fn panic_cold_explicit() -> ! {
                        $crate::panicking::panic_explicit()
                    }
                    panic_cold_explicit();
                }
            })
        } else {
            {
                #[cold]
                #[track_caller]
                #[inline(never)]
                const fn panic_cold_explicit() -> ! {
                    $crate::panicking::panic_explicit()
                }
                panic_cold_explicit();
            }
        })
        .set(v);
    }
    #[allow(non_snake_case)]
    fn m_y(&self) -> String {
        (if let __data__::__variant_Thingy::__data_Foo(o) =
            &self.0 .0 .0 .0.upgrade().unwrap().__variant
        {
            (if let __data__::__variant_Foo::__data_FooBar(o) = &o.__variant {
                (if let __data__::__variant_FooBar::__data_FooBarBar(o) = &o.__variant {
                    (&o.m_y)
                } else {
                    {
                        #[cold]
                        #[track_caller]
                        #[inline(never)]
                        const fn panic_cold_explicit() -> ! {
                            $crate::panicking::panic_explicit()
                        }
                        panic_cold_explicit();
                    }
                })
            } else {
                {
                    #[cold]
                    #[track_caller]
                    #[inline(never)]
                    const fn panic_cold_explicit() -> ! {
                        $crate::panicking::panic_explicit()
                    }
                    panic_cold_explicit();
                }
            })
        } else {
            {
                #[cold]
                #[track_caller]
                #[inline(never)]
                const fn panic_cold_explicit() -> ! {
                    $crate::panicking::panic_explicit()
                }
                panic_cold_explicit();
            }
        })
        .borrow()
        .clone()
    }
    #[allow(non_snake_case)]
    fn set_m_y(&self, v: String) {
        (if let __data__::__variant_Thingy::__data_Foo(o) =
            &self.0 .0 .0 .0.upgrade().unwrap().__variant
        {
            (if let __data__::__variant_Foo::__data_FooBar(o) = &o.__variant {
                (if let __data__::__variant_FooBar::__data_FooBarBar(o) = &o.__variant {
                    (&o.m_y)
                } else {
                    {
                        #[cold]
                        #[track_caller]
                        #[inline(never)]
                        const fn panic_cold_explicit() -> ! {
                            $crate::panicking::panic_explicit()
                        }
                        panic_cold_explicit();
                    }
                })
            } else {
                {
                    #[cold]
                    #[track_caller]
                    #[inline(never)]
                    const fn panic_cold_explicit() -> ! {
                        $crate::panicking::panic_explicit()
                    }
                    panic_cold_explicit();
                }
            })
        } else {
            {
                #[cold]
                #[track_caller]
                #[inline(never)]
                const fn panic_cold_explicit() -> ! {
                    $crate::panicking::panic_explicit()
                }
                panic_cold_explicit();
            }
        })
        .replace(v);
    }
    fn __ctor(&self, x: f64, y: &str) {
        self.set_m_x(x);
        self.set_m_y(y.into());
    }
    pub fn new(arena: &Arena, x: f64, y: &str) -> Self {
        let __cto1 = FooBarBar(FooBar(Foo(Thingy(
            arena
                .allocate(__data__::__data_Thingy {
                    __variant: __data__::__variant_Thingy::__data_Foo(::std::rc::Rc::new(
                        __data__::__data_Foo {
                            __variant: __data__::__variant_Foo::__data_FooBar(
                                ::std::rc::Rc::new(__data__::__data_FooBar {
                                    __variant: __data__::__variant_FooBar::__data_FooBarBar(
                                        ::std::rc::Rc::new(__data__::__data_FooBarBar {
                                            m_x: ::std::cell::Cell::new(0.0),
                                            m_y: ::std::cell::RefCell::new("".into()),
                                            __variant: __data__::__variant_FooBarBar::__Nothing,
                                        }),
                                    ),
                                }),
                            ),
                        },
                    )),
                })
                .clone(),
        ))));
        FooBar::__ctor(&__cto1.0);
        __cto1.__ctor(x, y);
        __cto1
    }
    fn __nd_name(&self) -> String {
        "FooBarBar".into()
    }
    fn __nd_x(&self) -> f64 {
        self.m_x()
    }
    fn __nd_base_example(&self) -> String {
        {
            let res = $crate::fmt::format(builtin #format_args(
                "from {}; {}",
                self.m_y(),
                FooBar::__nd_base_example(&self.0),
            ));
            res
        }
    }
    #[doc = " Empty, Foo, FooBar or FooQux"]
    pub fn name(&self) -> String {
        self.__nd_name()
    }
    pub fn x(&self) -> f64 {
        self.__nd_x()
    }
    pub fn base_example(&self) -> String {
        self.__nd_base_example()
    }
    pub fn to<T: TryFrom<FooBarBar, Error = crate::SModelError>>(
        &self,
    ) -> Result<T, crate::SModelError> {
        T::try_from(self.clone())
    }
    pub fn is<T: TryFrom<FooBarBar, Error = crate::SModelError>>(&self) -> bool {
        T::try_from(self.clone()).is_ok()
    }
}
impl FooQux {
    fn __ctor(&self) {}

    pub fn new(arena: &Arena) -> Self {
        let __cto1 = FooQux(Foo(Thingy(
            arena
                .allocate(__data__::__data_Thingy {
                    __variant: __data__::__variant_Thingy::__data_Foo(::std::rc::Rc::new(
                        __data__::__data_Foo {
                            __variant: __data__::__variant_Foo::__data_FooQux(
                                ::std::rc::Rc::new(__data__::__data_FooQux {
                                    __variant: __data__::__variant_FooQux::__Nothing,
                                }),
                            ),
                        },
                    )),
                })
                .clone(),
        )));
        Foo::__ctor(&__cto1.0);
        __cto1.__ctor();
        __cto1
    }
    fn __nd_name(&self) -> String {
        "FooQux".into()
    }
    #[doc = " Empty, Foo, FooBar or FooQux"]
    pub fn name(&self) -> String {
        self.__nd_name()
    }
    pub fn to<T: TryFrom<FooQux, Error = crate::SModelError>>(
        &self,
    ) -> Result<T, crate::SModelError> {
        T::try_from(self.clone())
    }
    pub fn is<T: TryFrom<FooQux, Error = crate::SModelError>>(&self) -> bool {
        T::try_from(self.clone()).is_ok()
    }
}
#[allow(non_camel_case_types, non_snake_case)]
mod __data__ {
    use super::*;
    pub enum __variant_Thingy {
        __data_Foo(::std::rc::Rc<__data_Foo>),
        __Nothing,
    }
    pub struct __data_Thingy {
        pub __variant: __variant_Thingy,
    }
    pub enum __variant_Foo {
        __data_FooBar(::std::rc::Rc<__data_FooBar>),
        __data_FooQux(::std::rc::Rc<__data_FooQux>),
        __Nothing,
    }
    pub struct __data_Foo {
        pub __variant: __variant_Foo,
    }
    pub enum __variant_FooBar {
        __data_FooBarBar(::std::rc::Rc<__data_FooBarBar>),
        __Nothing,
    }
    pub struct __data_FooBar {
        pub __variant: __variant_FooBar,
    }
    pub enum __variant_FooBarBar {
        __Nothing,
    }
    pub struct __data_FooBarBar {
        pub m_x: ::std::cell::Cell<f64>,
        pub m_y: ::std::cell::RefCell<String>,
        pub __variant: __variant_FooBarBar,
    }
    pub enum __variant_FooQux {
        __Nothing,
    }
    pub struct __data_FooQux {
        pub __variant: __variant_FooQux,
    }
}
Clone this wiki locally