| Crates.io | adar |
| lib.rs | adar |
| version | 0.1.0 |
| created_at | 2025-11-12 12:27:31.733319+00 |
| updated_at | 2025-11-12 12:27:31.733319+00 |
| description | Advanced Architecture (ADAR) is a collection of architectural tools that help you write more readable and performant code. |
| homepage | |
| repository | https://github.com/nandee95/adar/tree/main/adar |
| max_upload_size | |
| id | 1929216 |
| size | 115,210 |
Adar is a collection of architectural tools that help you write more readable and performant code.
Flags is a type-safe and verbose bitwise flag container. Most of the flag operations are inlined.
serde feature)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());
>> 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)
>> 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
}
}
...
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();
}
>> cargo run --example statemachine_trafficlight
Stop
🔴
⚫
⚫
... (5s)
GetReady
🔴
🟡
⚫
... (2s)
Go
⚫
⚫
🟢
... (5s)
StopIfSafe
⚫
🟡
⚫
... (2s, then repeats)
>> 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),
_ => {}
}
}
}
...
Reflects information about the enum and its variants.
#[repr(u8)])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,);
}
}
>> cargo run --example reflect_enum
Variants count: 3
Value1, Some(Value1)
Value2, None
Value3, None
>> 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",
}
}
}
...
Enables you to access a trait through an enum whose named variants implement the same trait.
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();
}
}
>> cargo run --example enum_trait_deref
Hello A
Hello B
>> 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,
}
}
}
...