linera_witty/util/
split.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Compile time splitting of heterogeneous lists.
5
6use frunk::{hlist, HCons, HNil};
7
8/// Compile time splitting of heterogeneous lists.
9///
10/// Allows splitting a heterogeneous list at a certain point, determined by the `Target` type,
11/// which should match this list type until a certain element. The list after that point is
12/// returned as the `Remainder` type.
13pub trait Split<Target> {
14    /// The tail of remaining elements after splitting up the list.
15    type Remainder;
16
17    /// Splits the current heterogeneous list in two.
18    fn split(self) -> (Target, Self::Remainder);
19}
20
21impl<AnyTail> Split<HNil> for AnyTail {
22    type Remainder = AnyTail;
23
24    fn split(self) -> (HNil, Self::Remainder) {
25        (hlist![], self)
26    }
27}
28
29impl<Head, SourceTail, TargetTail> Split<HCons<Head, TargetTail>> for HCons<Head, SourceTail>
30where
31    SourceTail: Split<TargetTail>,
32{
33    type Remainder = <SourceTail as Split<TargetTail>>::Remainder;
34
35    fn split(self) -> (HCons<Head, TargetTail>, Self::Remainder) {
36        let (tail, remainder) = self.tail.split();
37
38        (
39            HCons {
40                head: self.head,
41                tail,
42            },
43            remainder,
44        )
45    }
46}