Skip to content

improvement(dev-ex): compatible/identical types should be aliased and reused where possible #38

Open
@the-wondersmith

Description

@the-wondersmith

It would dramatically improve the crate's usability if instead of defining discrete types for every nested object within a CRD, compatible/identical types were defined once and automatically reused.

For example, the HeaderMatch type is identical between GRPCRoute and HTTPRoute resources, and do not require discrete handling when writing code to handle them. Another good example would be the way that HTTPRouteFilters are a superset of GRPCRouteFilters and can therefore also be handled by the same code without special consideration (i.e. any code that handles all HTTPRouteFilter types inherently also handles all GRPCRouteFilter types).

As the crate currently is, a dev would have to write such code with the newtype pattern or work a bit of black magic to skirt the orphan rule. A much more ergonomic solution would be if types that were actually the same to simply have exported aliases where you'd expect them to be ([example]) or for types where the compatible type is effectively a subset to impl From<SubsetType> for SupersetType ([example]).

In the case of aliased types, I'd imagine we'd want something like:

//! NOTE - module structure and naming are for
//! illustrative purposes only, actual real world
//! names and structure should be assumed to carry
//! on as they currently are

pub mod shared {
    // ...

    #[derive(
        Eq,
        Clone,
        // ...
    )]
    #[serde(tag = "type", rename_all = "PascalCase")]
    pub enum HeaderMatch {
        // ...
    }

   // ...
}

pub mod grpcroute {
    // ...

    pub type GRPCHeaderMatch = super::shared::HeaderMatch;

    // ...
}

pub mod httproute {
    // ...

    pub type HTTPHeaderMatch = super::shared::HeaderMatch;

    // ...
}

and in the case of compatible types:

//! NOTE - see note in example above re: naming and structure

pub mod shared {
    // ...

    #[derive(
        Eq,
        Clone,
        // ...
    )]
    #[serde(tag = "type", rename_all = "PascalCase")]
    pub struct RequestHeaderFilter {
        // ...
    }

    #[derive(
        Eq,
        Clone,
        // ...
    )]
    #[serde(tag = "type", rename_all = "PascalCase")]
    pub struct RequestMirrorFilter {
        // ...
    }

   // ...
}

pub mod grpcroute {
    // ...

    #[serde(tag = "type", rename_all = "PascalCase")]
    pub enum GrpcRouteFilter {
        // ...

        /// ...
        #[serde(rename_all = "camelCase")]
        RequestHeaderModifier {
            request_header_modifier: super::shared::RequestHeaderFilter,
        }

        // ...
    }

    impl From<GrpcRouteFilter> for super::httproute::HttpRouteFilter {
        // ...
    }
}

pub mod httproute {
    // ...

    #[serde(tag = "type", rename_all = "PascalCase")]
    pub enum HttpRouteFilter {
        // ...
    
        #[serde(rename_all = "camelCase")]
        RequestMirror {
            request_mirror: super::shared::RequestMirrorFilter,
        },

        /// ...
        #[serde(rename_all = "camelCase")]
        RequestHeaderModifier {
            request_header_modifier: super::shared::RequestHeaderFilter,
        }

       // ...
    }
}

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requesthelp wantedA community volunteer to work on this is wanted.priority/high

Type

Projects

Status

In Progress

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions