structural_typing/
split.rs1use core::marker::PhantomData;
7
8use crate::presence::{Absent, Optional, Presence, Present};
9
10pub trait Split<To: Presence>: Presence {
14 fn split<T>(value: Self::Output<T>) -> SplitResult<To, Self, T>
16 where
17 Self: Sized;
18}
19
20pub type SplitResult<To, From, T> = (
25 <To as Presence>::Output<T>,
26 <<To as Presence>::RemainderFrom<From> as Presence>::Output<T>,
27);
28
29pub trait TrySplit<To: Presence>: Presence {
34 fn try_split<T>(value: Self::Output<T>) -> Result<SplitResult<To, Self, T>, Self::Output<T>>
41 where
42 Self: Sized;
43}
44
45impl<From: Presence, To: Presence> TrySplit<To> for From
46where
47 From: Split<To>,
48{
49 fn try_split<T>(value: From::Output<T>) -> Result<SplitResult<To, From, T>, Self::Output<T>> {
50 Ok(From::split(value))
51 }
52}
53
54impl Split<Absent> for Present {
55 fn split<T>(value: T) -> (PhantomData<T>, T) {
56 (PhantomData, value)
57 }
58}
59
60impl Split<Present> for Present {
61 fn split<T>(value: T) -> (T, PhantomData<T>) {
62 (value, PhantomData)
63 }
64}
65
66impl Split<Optional> for Present {
67 fn split<T>(value: T) -> (Option<T>, PhantomData<T>) {
68 (Some(value), PhantomData)
69 }
70}
71
72impl Split<Absent> for Optional {
73 fn split<T>(value: Option<T>) -> (PhantomData<T>, Option<T>) {
74 (PhantomData, value)
75 }
76}
77
78impl Split<Optional> for Optional {
79 fn split<T>(value: Option<T>) -> (Option<T>, PhantomData<T>) {
80 (value, PhantomData)
81 }
82}
83
84impl TrySplit<Present> for Optional {
85 fn try_split<T>(value: Option<T>) -> Result<(T, PhantomData<T>), Option<T>> {
86 match value {
87 Some(v) => Ok((v, PhantomData)),
88 None => Err(None),
89 }
90 }
91}
92
93impl Split<Absent> for Absent {
94 fn split<T>(_value: PhantomData<T>) -> (PhantomData<T>, PhantomData<T>) {
95 (PhantomData, PhantomData)
96 }
97}
98
99impl Split<Optional> for Absent {
100 fn split<T>(_value: PhantomData<T>) -> (Option<T>, PhantomData<T>) {
101 (None, PhantomData)
102 }
103}