Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type checking specific entities types #15

Open
DGriffin91 opened this issue Nov 13, 2020 · 4 comments
Open

Type checking specific entities types #15

DGriffin91 opened this issue Nov 13, 2020 · 4 comments

Comments

@DGriffin91
Copy link

I'm trying to figure out if there is a better way to require a specific entity type. With the specific type being in an attribute of the entity I haven't been able to figure out a good way to do this yet.

This is currently a pattern I am using:

fn do_something_with_polylines(polyline: Entity) {
    let specific = if let EntityType::LwPolyline(ref specific) = polyline.specific {
        specific
    } else {
        panic!("Must use LwPolyline in box_kind()")
    };
}

Is there a better way to do this? I was hoping for something along these lines (Though I can see why it wouldn't work this way):

fn do_something_with_polylines(polyline: Entity<EntityType::LwPolyline>)

Sorry if this is something obvious as I'm fairly new to Rust.

In many cases I need have a function be able to access things in the .common attribute (Like what layer the Entity) so it is not practical to only pass the .specific attribute to the function.

@brettfo
Copy link
Member

brettfo commented Nov 13, 2020

As far as I'm aware there's not a way to pattern match in the function signature like you suggested. Even if there was a bare enum field on the root object, you'd still have to check it in the function body like you're doing in your example.

@DGriffin91
Copy link
Author

In case it's on any interest to you, I ended up doing this: https://gist.github.com/DGriffin91/77390c206a841fc9b87ab0a11df152d8

I'm just changing the layout of the types.

I'm not really sure if this is the best way to do this, and it feels a bit excessive. But it's made the rest of my code base much cleaner. And thanks to multiple cursors in VSCode it was easy to implement.

I can then have functions like this:

fn do_something_with_polylines_and_inserts(polylines: &ddxf::DLwPolyline, inserts: ddxf::DInsert) -> ddxf::DInsert

I just convert types on when I import:

let mut dwg = Drawing::load_file("some_file.dxf").expect("");
let mut entities = ddxf::convert_entities(dwg);

Then extract specific types:

pub fn polylines(entities: &Vec<ddxf::DEntity>) -> Vec<ddxf::DLwPolyline>

@brettfo
Copy link
Member

brettfo commented Nov 17, 2020

Thanks for looking at this. I'll experiment a bit to see if inverting the type composition makes other scenarios easier/harder.

@DGriffin91
Copy link
Author

DGriffin91 commented Nov 17, 2020

Thanks for looking into this!

I haven't played around with it, but I think it might be even better if it was structured like this with the specific fields directly in the main struct:

struct Line {
    thickness: f64,
    p1: Point,
    p2: Point,
    extrusion_direction: Vector,
    common: EntityCommon,
}

I'm not entirely sure since I am fairly new to Rust and this crate in particular. And I'm obviously much more aware of the implications in my own use of the crate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants