airlang 0.26.0

Air is a minimalist and universal programming language.
Documentation
use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Write;
use std::str::FromStr;

use derive_more::From;
use derive_more::IsVariant;

use super::ParseError;
use super::ReprType;
use super::generator::FmtOptions;
use super::generator::FmtRepr;
use super::impl_display_debug_for_fmt_repr;
use super::parser::ParseRepr;
use super::parser::parse;
use crate::type_::Bit;
use crate::type_::Byte;
use crate::type_::Call;
use crate::type_::Cell;
use crate::type_::Decimal;
use crate::type_::Int;
use crate::type_::Key;
use crate::type_::List;
use crate::type_::Map;
use crate::type_::Pair;
use crate::type_::Quote;
use crate::type_::Solve;
use crate::type_::Text;
use crate::type_::Unit;

#[derive(Clone, PartialEq, Eq, Hash, From, IsVariant)]
pub enum Repr {
    Unit(Unit),
    Bit(Bit),

    Key(Key),

    Text(Text),
    Int(Int),
    Decimal(Decimal),
    Byte(Byte),

    Cell(Box<CellRepr>),
    Pair(Box<PairRepr>),
    List(ListRepr),
    Map(MapRepr),

    Quote(Box<QuoteRepr>),
    Call(Box<CallRepr>),
    Solve(Box<SolveRepr>),
}

pub type CellRepr = Cell<Repr>;

pub type PairRepr = Pair<Repr, Repr>;

pub type ListRepr = List<Repr>;

pub type MapRepr = Map<Key, Repr>;

pub type QuoteRepr = Quote<Repr>;

pub type CallRepr = Call<Repr, Repr>;

pub type SolveRepr = Solve<Repr, Repr>;

impl Default for Repr {
    fn default() -> Self {
        Repr::Unit(Unit)
    }
}

impl From<CellRepr> for Repr {
    fn from(cell: CellRepr) -> Self {
        Repr::Cell(Box::new(cell))
    }
}

impl From<PairRepr> for Repr {
    fn from(pair: PairRepr) -> Self {
        Repr::Pair(Box::new(pair))
    }
}

impl From<QuoteRepr> for Repr {
    fn from(quote: QuoteRepr) -> Self {
        Repr::Quote(Box::new(quote))
    }
}

impl From<CallRepr> for Repr {
    fn from(call: CallRepr) -> Self {
        Repr::Call(Box::new(call))
    }
}

impl From<SolveRepr> for Repr {
    fn from(solve: SolveRepr) -> Self {
        Repr::Solve(Box::new(solve))
    }
}

impl ParseRepr for Repr {}

impl FromStr for Repr {
    type Err = ParseError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        parse(s)
    }
}

impl FmtRepr for Repr {
    fn fmt(&self, options: FmtOptions, f: &mut dyn Write) -> std::fmt::Result {
        match self {
            Repr::Unit(unit) => <Unit as FmtRepr>::fmt(unit, options, f),
            Repr::Bit(bit) => <Bit as FmtRepr>::fmt(bit, options, f),
            Repr::Key(key) => <Key as FmtRepr>::fmt(key, options, f),
            Repr::Text(text) => <Text as FmtRepr>::fmt(text, options, f),
            Repr::Int(int) => <Int as FmtRepr>::fmt(int, options, f),
            Repr::Decimal(decimal) => <Decimal as FmtRepr>::fmt(decimal, options, f),
            Repr::Byte(byte) => <Byte as FmtRepr>::fmt(byte, options, f),
            Repr::Cell(cell) => <CellRepr as FmtRepr>::fmt(cell, options, f),
            Repr::Pair(pair) => <PairRepr as FmtRepr>::fmt(pair, options, f),
            Repr::List(list) => <ListRepr as FmtRepr>::fmt(list, options, f),
            Repr::Map(map) => <MapRepr as FmtRepr>::fmt(map, options, f),
            Repr::Quote(quote) => <QuoteRepr as FmtRepr>::fmt(quote, options, f),
            Repr::Call(call) => <CallRepr as FmtRepr>::fmt(call, options, f),
            Repr::Solve(solve) => <SolveRepr as FmtRepr>::fmt(solve, options, f),
        }
    }

    fn get_type(&self) -> ReprType {
        match self {
            Repr::Unit(_) => ReprType::Unit,
            Repr::Bit(_) => ReprType::Bit,
            Repr::Key(_) => ReprType::Key,
            Repr::Text(_) => ReprType::Text,
            Repr::Int(_) => ReprType::Int,
            Repr::Decimal(_) => ReprType::Decimal,
            Repr::Byte(_) => ReprType::Byte,
            Repr::Cell(_) => ReprType::Cell,
            Repr::Pair(_) => ReprType::Pair,
            Repr::List(_) => ReprType::List,
            Repr::Map(_) => ReprType::Map,
            Repr::Quote(_) => ReprType::Quote,
            Repr::Call(_) => ReprType::Call,
            Repr::Solve(_) => ReprType::Solve,
        }
    }

    fn to_pair(&self) -> Pair<&dyn FmtRepr, &dyn FmtRepr> {
        let Repr::Pair(pair) = self else {
            panic!("called `FmtRepr::to_pair()` on non-pair value")
        };
        Pair::new(&pair.left, &pair.right)
    }
}

impl_display_debug_for_fmt_repr!(Repr);