rodrimati1992 / tstr_crates

Type-level strings
zlib License
9 stars 1 forks source link

Main example can be easily achieved with traits #8

Closed mickvangelderen closed 4 days ago

mickvangelderen commented 1 week ago

I stumbled upon this crate and wondered what the point was. The main example does not help me. Particularly, the equivalent dependency-free version can be written with some simple traits:

fn main() {
    takes_person(&Person::new("Bob".into(), "Marley".into()));

    takes_person(&OtherPerson::new("Bob", "Marley"));
}

trait HasName {
    fn name(&self) -> &str;
}

trait HasSurname {
    fn surname(&self) -> &str;
}

fn takes_person<P>(pers: &P)
where
    P: HasName + HasSurname,
{
    assert_eq!(pers.name(), "Bob");
    assert_eq!(pers.surname(), "Marley");
}

use person::Person;
mod person {
    use super::{HasName, HasSurname};

    pub struct Person {
        name: String,
        surname: String,
    }

    impl Person {
        pub fn new(name: String, surname: String) -> Self {
            Self { name, surname }
        }
    }

    impl HasName for Person {
        fn name(&self) -> &str {
            &self.name
        }
    }

    impl HasSurname for Person {
        fn surname(&self) -> &str {
            &self.surname
        }
    }
}

use other_person::OtherPerson;
mod other_person {
    use super::{HasName, HasSurname};

    pub struct OtherPerson {
        name: &'static str,
        surname: &'static str,
    }

    impl OtherPerson {
        pub fn new(name: &'static str, surname: &'static str) -> Self {
            Self { name, surname }
        }
    }

    impl HasName for OtherPerson {
        fn name(&self) -> &str {
            &self.name
        }
    }

    impl HasSurname for OtherPerson {
        fn surname(&self) -> &str {
            &self.surname
        }
    }
}

What am I missing?

rodrimati1992 commented 1 week ago

The problem is that now to encode getters you need to know about a specific trait to get a specific field, whereas with type-level strings you only need to know about a single generic trait for all fields. The latter also allows being generic over field names, which would allow blanketly delegating all getters to a field.

mickvangelderen commented 1 week ago

The problem is that now to encode getters you need to know about a specific trait to get a specific field, whereas with type-level strings you only need to know about a single generic trait for all fields.

With type-level strings you need to know about a single generic trait, but also the name of each field. To me, knowing the names of each trait and method versus knowing the names of each type level string is the same.

The latter also allows being generic over field names, which would allow blanketly delegating all getters to a field.

Maybe it would be good to highlight this in the example, and show why that can be useful?