Home > OS >  Constrain generic types by associated type in trait
Constrain generic types by associated type in trait

Time:10-23

I am trying to accomplish the following:

Define a generic class, have this class take in an abstract data type with a trait and initialize itself using some known methods, something like this:

struct Edge<MetaData>
{
    next_id: u64,
    prev_id: u64,
    pair_id: u64,

    vert_id: u64,

    face_id: u64,

    meta_data: MetaData,
}

impl<MetaData> Edge<MetaData>
{
    fn new(vert_id: u64, pair_id: u64, data: MetaData) -> Self
    {
        return Self {
            next_id: !0,
            prev_id: !0,
            pair_id,
            vert_id,
            face_id: !0,
            meta_data: data,
        };
    }
}

struct HalfMesh<
    VMetaData,
    EMetaData,
    FMetaData,
> {
    verts: Vec<Vert<VMetaData>>,
    edges: Vec<Edge<EMetaData>>,
    faces: Vec<Face<FMetaData>>,
}

impl<V, E, F> HalfMesh<V, E, F>
{
    fn new_mesh<T>(data: T)
    where T :MeshData
    {
        let topology = data.get_topology();
        let half_edges = HashMap::<(u64, u64), usize>::new();

        let verts = Vec::<Vert<V>>::new();
        let edges = Vec::<Edge<E>>::new();
        let faces = Vec::<Face<F>>::new();

        for (face_id, face) in topology.iter().enumerate()
        {
            for i in 0..face.len()
            {
                let face_id = face_id as u64;
                let edge1 = (face[i], face[(i   1) % face.len()]);
                if half_edges.contains_key(&edge1)
                {
                    continue;
                }

                let n = edges.len() as u64;
                edges.push(Edge::new(n   1, edge1.0, data.get_edge_data(face_id, i as u64)));
            }
        }
    }
}

trait MeshData
{
    type VertData;
    type EdgeData;
    type FaceData;

    fn get_vert_data(&self, vert_id: u64) -> Self::VertData;
    fn get_edge_data(&self, face_id: u64, edge_id: u64) -> Self::EdgeData;
    fn get_face_data(&self, face_id: u64) -> Self::FaceData;

    fn get_topology(&self) -> &Vec<Vec<u64>>;
}

This however is returning the error:

64 | impl<V, E, F> HalfMesh<V, E, F>
   |         - this type parameter
...
88 |                 edges.push(Edge::new(n   1, edge1.0, data.get_edge_data(face_id, i as u64)));
   |                            ---------                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `E`, found associated type
   |                            |
   |                            arguments to this function are incorrect

It makes sense, E is the generic type and the associated type MeshData::EdgeData is not constrained to be equal to E.

But then i don;t know how to tell rust, yeah btw, constrain HalfMesh such that it can be initialized by the types in MeshData :\

CodePudding user response:

It looks like you forgot to specify the types for the associated types:

 new_mesh<T>(data: T)
where T: MeshData<
VertData = V,
EdgeData = E,
FaceData = F,
> {

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b8c166a7380bb4c58a60a6eaf2954714

  • Related