Trait bounds on deeply nested gat are really cumbersome

Hi I have the following function signature:

fn behavior<B, const N: usize>(state: &mut State<B>, tx1: &SyncSender<Output1<N>>) -> Option<i64>
where
    B: Book,
    <<B as Book>::BidBookSideType as BookSide>::BookLevelType: L2BookLevel,
    <<B as Book>::AskBookSideType as BookSide>::BookLevelType: L2BookLevel,
    <<<B as Book>::BidBookSideType as BookSide>::BookLevelType as L2BookLevel>::PriceType:
        Price<RawPriceType = <<<<B as Book>::AskBookSideType as BookSide>::BookLevelType as L2BookLevel>::PriceType as Price>::RawPriceType>,
    <<<B as Book>::BidBookSideType as BookSide>::BookLevelType as L2BookLevel>::QtyType:
        Qty<RawQtyType = <<<<B as Book>::AskBookSideType as BookSide>::BookLevelType as L2BookLevel>::QtyType as Qty>::RawQtyType>;

Just writing this signature took quite a bit of effort (getting the brackets right, and just figuring out how to express what I had in mind was quite a pain)

What are some general strategies to deal with this?

1 Like

Calmdown there, Satan.

I'm not sure why you are using this much nested trait, but you can use type aliases in this case.

trait Book {
    type BidBookSide: BookSide;
    type AskBookSide: BookSide;
}

trait BookSide {
    type BookLevelType: L2BookLevel;
}

trait L2BookLevel {
    type PriceType: Price;
}

trait Price {
    type RawPriceType;
}

type BidLevelType<B> = <<B as Book>::BidBookSide as BookSide>::BookLevelType;
type AskLevelType<B> = <<B as Book>::AskBookSide as BookSide>::BookLevelType;
type PriceType<B> = <B as L2BookLevel>::PriceType;
type RawPriceType<B> = <PriceType<B> as Price>::RawPriceType;

fn behavior<B>()
where
    B: Book,
    BidLevelType<B>: L2BookLevel,
    PriceType<BidLevelType<B>>: Price<RawPriceType = RawPriceType<AskLevelType<B>>>,
{}

Playground

6 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.