adar

Crates.ioadar
lib.rsadar
version0.1.0
created_at2025-11-12 12:27:31.733319+00
updated_at2025-11-12 12:27:31.733319+00
descriptionAdvanced Architecture (ADAR) is a collection of architectural tools that help you write more readable and performant code.
homepage
repositoryhttps://github.com/nandee95/adar/tree/main/adar
max_upload_size
id1929216
size115,210
Nándor Szalma (nandee95)

documentation

https://docs.rs/adar

README

Advanced Architecture (ADAR)

Crates.io Downloads Docs

Adar is a collection of architectural tools that help you write more readable and performant code.

Flags

Flags is a type-safe and verbose bitwise flag container. Most of the flag operations are inlined.

Features

  • Union, Intersect
  • Serialization (requires serde feature)
  • Conversion to and from raw values
  • Intuitive syntax

Example

use adar::prelude::*;

#[FlagEnum]
enum MyFlag {F1, F2, F3}

let mut a = Flags::from(MyFlag::F1);
a.set(MyFlag::F2);
let mut b = MyFlag::F1 | MyFlag::F2 | MyFlag::F3;
b.reset(MyFlag::F1);

println!("a: {:?}, {:03b}", a, a.into_raw());
println!("b: {:?}, {:03b}", b, b.into_raw());

println!("a.any(F1,F3): {:?}", a.any(MyFlag::F1 | MyFlag::F3));
println!("a.all(F1,F3): {:?}", a.all(MyFlag::F1 | MyFlag::F3));

println!("a.intersect(b): {:?}", a.intersect(b));
println!("a.union(b): {:?}", a.union(b));
println!("full(): {:?}", Flags::<MyFlag>::full());
Click to see the output >> cargo run --example flags
a: (F1,F2), 011
b: (F2,F3), 110
a.any(F1,F3): true
a.all(F1,F3): false
a.intersect(b): (F2)
a.union(b): (F1,F2,F3)
full(): (F1,F2,F3)
Click to see the generated code >> cargo expand --example flags
...
#[repr(u32)]
enum MyFlag {
    F1 = 1,
    F2 = 2,
    F3 = 4,
}
...
impl std::ops::BitOr for MyFlag
where
    Self: adar::prelude::ReflectEnum,
{
    type Output = adar::prelude::Flags<Self>;
    fn bitor(self, rhs: Self) -> Self::Output {
        Flags::empty() | self | rhs
    }
}
...

StateMachine

Features

Example

use adar::prelude::*;
use std::{process::Command, time::Duration};

#[StateEnum]
#[ReflectEnum] // Optional. (Used here to print the name of the state)
enum TrafficLight {
    Go,
    GetReady,
    StopIfSafe,
    Stop,
}

impl TrafficLight {
    const YELLOW_DURATION: Duration = Duration::from_secs(1);
    const GO_STOP_DURATION: Duration = Duration::from_secs(2);
}

impl Machine for TrafficLight {
    fn on_transition(&mut self, new_state: &Self::States, _context: &mut Self::Context) {
        Command::new("clear")
            .status()
            .expect("Failed to clear screen!");

        println!("{}", new_state.name());
    }
}

impl State for Go {
    fn on_enter(&mut self, _args: Option<&mut Self::Args>, _context: &mut Self::Context) {
        println!("⚫\n⚫\n🟢");
    }
    fn on_update(
        &mut self,
        _args: Option<&mut Self::Args>,
        _context: &mut Self::Context,
    ) -> Option<Self::States> {
        std::thread::sleep(TrafficLight::GO_STOP_DURATION);
        Some(StopIfSafe.into())
    }
}

impl State for GetReady {
    fn on_enter(&mut self, _args: Option<&mut Self::Args>, _context: &mut Self::Context) {
        println!("🔴\n🟡\n⚫");
    }
    fn on_update(
        &mut self,
        _args: Option<&mut Self::Args>,
        _context: &mut Self::Context,
    ) -> Option<Self::States> {
        std::thread::sleep(TrafficLight::YELLOW_DURATION);
        Some(Go.into())
    }
}

impl State for StopIfSafe {
    fn on_enter(&mut self, _args: Option<&mut Self::Args>, _context: &mut Self::Context) {
        println!("⚫\n🟡\n⚫");
    }
    fn on_update(
        &mut self,
        _args: Option<&mut Self::Args>,
        _context: &mut Self::Context,
    ) -> Option<Self::States> {
        std::thread::sleep(TrafficLight::YELLOW_DURATION);
        Some(Stop.into())
    }
}

impl State for Stop {
    fn on_enter(&mut self, _args: Option<&mut Self::Args>, _context: &mut Self::Context) {
        println!("🔴\n⚫\n⚫")
    }
    fn on_update(
        &mut self,
        _args: Option<&mut Self::Args>,
        _context: &mut Self::Context,
    ) -> Option<Self::States> {
        std::thread::sleep(TrafficLight::GO_STOP_DURATION);
        Some(GetReady.into())
    }
}

fn main() {
    StateMachine::new(Stop).run();
}
Click to see the output >> cargo run --example statemachine_trafficlight
Stop
🔴
⚫
⚫
... (5s)
GetReady
🔴
🟡
⚫
... (2s)
Go
⚫
⚫
🟢
... (5s)
StopIfSafe
⚫
🟡
⚫
... (2s, then repeats)
Click to see the generated code >> cargo expand --example statemachine_trafficlight
...
enum TrafficLight {
    Go(Go),
    GetReady(GetReady),
    StopIfSafe(StopIfSafe),
    Stop(Stop),
}
impl adar::prelude::ReflectEnum for TrafficLight {
    type Type = u32;
    fn variants() -> &'static [adar::prelude::EnumVariant<TrafficLight>] {
        const VARIANTS: &[adar::prelude::EnumVariant<TrafficLight>] = &[
            EnumVariant::new("Go", None),
            EnumVariant::new("GetReady", None),
            EnumVariant::new("StopIfSafe", None),
            EnumVariant::new("Stop", None),
        ];
        VARIANTS
    }
    fn count() -> usize {
        4usize
    }
    fn name(&self) -> &'static str {
        match self {
            Self::Go { .. } => "Go",
            Self::GetReady { .. } => "GetReady",
            Self::StopIfSafe { .. } => "StopIfSafe",
            Self::Stop { .. } => "Stop",
        }
    }
}
struct Go;
impl adar::prelude::StateTypes for Go {
    type States = TrafficLight;
    type Args = ();
    type Context = ();
}
impl Into<TrafficLight> for Go {
    fn into(self) -> TrafficLight {
        TrafficLight::Go(self)
    }
}
struct GetReady;
impl adar::prelude::StateTypes for GetReady {
    type States = TrafficLight;
    type Args = ();
    type Context = ();
}
impl Into<TrafficLight> for GetReady {
    fn into(self) -> TrafficLight {
        TrafficLight::GetReady(self)
    }
}
struct StopIfSafe;
impl adar::prelude::StateTypes for StopIfSafe {
    type States = TrafficLight;
    type Args = ();
    type Context = ();
}
impl Into<TrafficLight> for StopIfSafe {
    fn into(self) -> TrafficLight {
        TrafficLight::StopIfSafe(self)
    }
}
struct Stop;
impl adar::prelude::StateTypes for Stop {
    type States = TrafficLight;
    type Args = ();
    type Context = ();
}
impl Into<TrafficLight> for Stop {
    fn into(self) -> TrafficLight {
        TrafficLight::Stop(self)
    }
}
impl adar::prelude::StateTypes for TrafficLight {
    type States = Self;
    type Args = ();
    type Context = ();
}
impl adar::prelude::State for TrafficLight {
    fn on_enter(&mut self, args: Option<&mut Self::Args>, context: &mut Self::Context) {
        match self {
            Self::Go(s) => Go::on_enter(s, args, context),
            Self::GetReady(s) => GetReady::on_enter(s, args, context),
            Self::StopIfSafe(s) => StopIfSafe::on_enter(s, args, context),
            Self::Stop(s) => Stop::on_enter(s, args, context),
            _ => {}
        }
    }
    fn on_update(
        &mut self,
        args: Option<&mut Self::Args>,
        context: &mut Self::Context,
    ) -> Option<Self::States> {
        match self {
            Self::Go(s) => Go::on_update(s, args, context),
            Self::GetReady(s) => GetReady::on_update(s, args, context),
            Self::StopIfSafe(s) => StopIfSafe::on_update(s, args, context),
            Self::Stop(s) => Stop::on_update(s, args, context),
            _ => None,
        }
    }
    fn on_leave(&mut self, args: Option<&mut Self::Args>, context: &mut Self::Context) {
        match self {
            Self::Go(s) => Go::on_leave(s, args, context),
            Self::GetReady(s) => GetReady::on_leave(s, args, context),
            Self::StopIfSafe(s) => StopIfSafe::on_leave(s, args, context),
            Self::Stop(s) => Stop::on_leave(s, args, context),
            _ => {}
        }
    }
}
...

Reflect Enum

Reflects information about the enum and its variants.

Features

Example

use adar::prelude::*;

#[ReflectEnum]
#[repr(u32)]
#[derive(Debug)]
enum MyEnum {
    Value1 = 33,
    Value2(i32),
    Value3 { a: String },
}

fn main() {
    println!("Variants count: {}", MyEnum::count());
    for variant in MyEnum::variants() {
        println!("{}, {:?}", variant.name, variant.value,);
    }
}
Click to see the output >> cargo run --example reflect_enum
Variants count: 3
Value1, Some(Value1)
Value2, None
Value3, None
Click to see the generated code >> cargo expand --example reflect_enum
...
impl adar::prelude::ReflectEnum for MyEnum {
    type Type = u32;
    fn variants() -> &'static [adar::prelude::EnumVariant<MyEnum>] {
        const VARIANTS: &[adar::prelude::EnumVariant<MyEnum>] = &[
            EnumVariant::new("Value1", Some(MyEnum::Value1)),
            EnumVariant::new("Value2", None),
            EnumVariant::new("Value3", None),
        ];
        VARIANTS
    }
    fn count() -> usize {
        3usize
    }
    fn name(&self) -> &'static str {
        match self {
            Self::Value1 { .. } => "Value1",
            Self::Value2 { .. } => "Value2",
            Self::Value3 { .. } => "Value3",
        }
    }
}
...

Enum Trait Deref

Enables you to access a trait through an enum whose named variants implement the same trait.

Features

Example

use adar::prelude::*;

trait MyTrait {
    fn my_func(&self);
}

#[EnumTraitDeref(MyTrait)]
enum MyEnum {
    A(A),
    B(B),
}

#[derive(Clone)]
struct A;

#[derive(Clone)]
struct B;

impl MyTrait for A {
    fn my_func(&self) {
        println!("Hello A");
    }
}

impl MyTrait for B {
    fn my_func(&self) {
        println!("Hello B");
    }
}

fn main() {
    for e in [MyEnum::A(A), MyEnum::B(B)] {
        e.my_func();
    }
}
Click to see the output >> cargo run --example enum_trait_deref
Hello A
Hello B
Click to see the generated code >> cargo expand --example enum_trait_deref
...
impl ::core::ops::Deref for MyEnum {
    type Target = dyn MyTrait;
    fn deref(&self) -> &Self::Target {
        match self {
            Self::A(v) => v as &Self::Target,
            Self::B(v) => v as &Self::Target,
        }
    }
}
...
Commit count: 0

cargo fmt