#Super simple question about rust language

4 messages · Page 1 of 1 (latest)

patent patio
#

I would like to implement a generic function that takes in a string that has 3 entries separated by spaces, and either parses it to a glam::Vec3 or a glam::IVec3depending on whether a generic type parameter is f32 or i32. This generic type is known at compile time, i.e. the "angle bracket" generic syntax.

The biggest reason I can't seem to get started implementing it is that I don't know how to switch on a generic type. In typescript one could use instanceof but that doesn't really work here.

Please provide a suggestion on how to get started.

candid orchid
#

The replacement for switching on a type is a helper trait:

//first, the helper trait
pub trait FromStrTriplet {
  fn from_str_triplet(from: &str) -> Self;
}
//then, the impls
impl FromStrTriplet for Vec3 {
  fn from_str_triplet(from: &str) -> Self {
    let (x, y, z) = parse_triplet(from);
    Vec3::new(x, y, z);
  }
}
impl FromStrTriplet for IVec3 {
  fn from_str_triplet(from: &str) -> Self {
    let (x, y, z) = parse_triplet(from);
    IVec3::new(x, y, z);
  }
}

//finally, the actual function:
pub fn parse_str_triplet<T: FromStrTriplet>(from: &str) -> T {
  T::from_str_triplet(from)
}

//this is just for convenience implementing the traits.
fn parse_triplet<T: FromStr>(from: &str) -> (T, T, T) {
  let mut iter = from
    .split_whitespace
    .take(3)
    .map(|coord| coord.parse().unwrap());
  (iter.next().unwrap(), iter.next().unwrap(), iter.next().unwrap(): //better error handling left as an exercise for the reader
}
#

parse_str_triplet ends up existing just as a convenience method over calling T::from_str_triplet. This is generally more useful if it's a method on something else, like how .collect::<T>() on iterators just calls T::from_iter internally

patent patio
#

Although it's idiomatic, it seems a bit verbose. For right now, I have some repetitive code but tis fine for my purposes. In the future, I might implement a struct called StrTripletParser.