oors

Crates.iooors
lib.rsoors
version0.9.2
created_at2025-09-09 01:24:25.029392+00
updated_at2025-09-16 03:15:52.849233+00
descriptionAdding cross-crate inheritance features to Rust structs
homepage
repositoryhttps://gitlab.com/eligamii/oors
max_upload_size
id1830115
size29,205
eligamii (eligamii)

documentation

README

oors - Inheritance in Rust

A little experiment in adding cross-crate inheritance features to Rust structs using a single #[oors::object] macro.

Example

crate_a:

#[derive(Default)]
#[oors::object] 
pub struct Animal { // Is a #[repr(C)] struct
   age: u8, 
   name: String,
}

#[oors::object]
pub struct Insect {
   dangerous: bool,
   speed_in_kmh: usize
}

#[derive(Default)]
#[oors::object(parent = Animal)] 
pub struct Dog { 
   // Gets a `base: Animal,` at offset 0 of self
   wants_to_play: bool,
   is_angry: bool,
   /// Each word that the dog understand (like "come")
   learnt: Vec<String> 
}

#[object_impl]
impl Dog {
   // Implemented for Dog
   pub fn new(name: String) -> Typed<Self> {
       Dog::from_value(Default::default())
           .with_name(name)
           .build()
   }
 
   // Implemented for IsA<Dog> (Dog and all of its children)
   fn bark(&self) {
       match *self.age_ref() { // <-- Access to Animal's fields
           a if a < 1 => println!("Wif! Wif!"),
           b if b > 1 && b < 7 => println!("Wouf!"),
           c if c < 15 => println!("Waf!"),
           _ => println!("Wouf...")
       }
   }
}


crate_b:

// This is necessary for #[object] to work with crate_a's types
// alternatively, you can use the `#[obj_use]` macro along with the
// feature "nightly"
 use crate_a::*; 
 #[oors::object(parent = Dog)]
 pub struct Husky {
    /// The number of kilometers that the dog is capable of running
    energy_left: usize
 }
 
 fn main() {
    let husky = Husky::builder()
        .insert_value(Dog::new("Max")) // <- Equivalent to a `..Dog::new(...)` in struct expression
        .with_learnt(vec!["Donne la pa-patte", "Couché", "Debout"])
        .with_energy_left(usize::MAX) // <- Gets the documentation of `Husky`
        .build(); // Fails if not all of its fields were implemented
                  
    let animal = husky.upcast_ref::<Animal>(); // This is a &oors::Typed<Animal>
    // `husky.upcast_ref::<Insect>()` doesn't compile as Husky doesn't impl IsA<Insect>
    get_genome(animal);
  
    // Actually, `animal` is still a Husky
    let still_husky = animal.try_cast_ref::<Husky>().unwrap();
    
    still_husky.bark(); // <-- Access `Dog`'s methods
    
    // Typed store the *actual* type of Husky and all of its parents
    still_husky.try_cast_ref::<Insect>().unwrap_err();
 }

Commit count: 26

cargo fmt