abstract-impl 0.1.0

Create abstract implementations for traits
Documentation

Abstract Impl

This crate enables users to generate generic (abstract) implementations for traits, with bounds on the Self type.

The idea for this came primarily from Context-Generic Programming, I wanted the core without all the bells and whistles (no providers, consumers and contexts). I noticed that it primarily empowers the programmer to provide generic implementations for traits, that types can choose to implement.

The name abstract_impl comes from the possibility of having that in rust (abstract is a reserved keyword), you could have abstract impl.

Use

use abstract_impl::abstract_impl;
mod traits {
    pub trait FormatToString {
        type Error;
        fn format_to_string(&self) -> Result<String, Self::Error>;
    }

    pub trait Print {
        type Error;
        fn print(&self) -> Result<(), Self::Error>;
    }
}
use traits::*;

mod impls {
    use super::*;

    #[abstract_impl]
    impl FormatToString for FormatUsingDebug
    where
        Self: std::fmt::Debug,
    {
        type Error = ();
        fn format_to_string(&self) -> Result<String, Self::Error> {
            Ok(format!("{context:?}"))
        }
    }

    #[derive(Debug)]
    pub enum PrintUsingFormatErr<FormatErr> {
        Other,
        FormatErr(FormatErr),
    }
    #[abstract_impl]
    impl Print for PrintUsingFormat
    where
        Self: FormatToString,
    {
        type Error = PrintUsingFormatErr<<Self as FormatToString>::Error>;
        fn print(&self) -> Result<(), Self::Error> {
            let string = self.format_to_string().map_err(Self::Error::FormatErr)?;
            Ok(println!("{string}"))
        }
    }
    #[abstract_impl]
    impl Print for PrintDummy {
        type Error = ();
        fn print(&self) -> Result<(), ()> {
            Ok(println!("Hi"))
        }
    }
    #[abstract_impl(no_dummy)]
    impl std::cmp::PartialOrd for PartialUsingOrd
    where
        Self: Ord,
    {
        fn partial_cmp(&self, rhs: &Self) -> Option<std::cmp::Ordering> {
            Some(self.cmp(rhs))
        }
    }
}
use impls::*;

#[derive(Debug)]
struct Person {
    pub first_name: String,
    pub last_name: String,
}

impl_FormatUsingDebug!(Person);
impl_PrintUsingFormat!(Person);

fn main() {
    Person {
        first_name: "Alice".to_string(),
        last_name: "B.".to_string(),
    }
    .print()
    .unwrap();
}

No Macro

No Dummy

How it is made

License

This code is MIT licensed.