Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement std::convert::From on type from another crate

Tags:

rust

I have an external geometry crate that defines a rectangle struct made of floats and an external sdl2 crate that defines a rectangle struct made of integers.

The following code is how I would expect to convert a geometry::Rect to an sdl2::SdlRect using the std::convert::From trait:

extern crate geometry;
extern crate sdl2;

fn main() {
    let geo_rect = geometry::Rect::default();
    let sdl_rect = sdl2::SdlRect::from(geo_rect);
}

impl From<geometry::Rect> for sdl2::SdlRect {
    fn from (rect: geometry::Rect) -> sdl2::SdlRect {
        sdl2::SdlRect {
            x: rect.x as i32,
            y: rect.y as i32,
            w: rect.w as i32,
            h: rect.h as i32,
        }
    }
}

Unfortunately, this doesn't compile because either the trait I'm implementing or the struct it's being implemented for must come from the current crate. The only solution I've found that works is to define a MyFrom trait that mirrors the functionality of the std::convert::From trait:

extern crate geometry;
extern crate sdl2;

fn main() {
    let geo_rect = geometry::Rect::default();
    let sdl_rect = sdl2::SdlRect::my_from(geo_rect);
}

pub trait MyFrom<T> {
    fn my_from(T) -> Self;
}

impl MyFrom<geometry::Rect> for sdl2::SdlRect {
    fn my_from (rect: geometry::Rect) -> sdl2::SdlRect {
        sdl2::SdlRect {
            x: rect.x as i32,
            y: rect.y as i32,
            w: rect.w as i32,
            h: rect.h as i32,
        }
    }
}

I'm not particularly happy with this solution because knowing when to call my_from instead of from will get confusing down the line. Is there another way for me to solve this using more idiomatic Rust?

like image 706
Brian Avatar asked Jul 25 '26 08:07

Brian


1 Answers

Better define your own rectangle type that wraps an externally defined rectangle, and use the standard From trait.

This is one possible use of the newtype pattern.

like image 173
starblue Avatar answered Jul 28 '26 06:07

starblue