@@ -2,13 +2,23 @@ use std::{str::FromStr, sync::Arc};
22
33use crate :: { base:: { schema:: BasicValueType , value:: BasicValue } , prelude:: * } ;
44
5+ #[ derive( Debug , Clone ) ]
6+ pub enum UnionParseResult {
7+ Union ( UnionType ) ,
8+ Single ( BasicValueType ) ,
9+ }
10+
511/// Union type helper storing an auto-sorted set of types excluding `Union`
6- #[ derive( Debug , Clone , Default , Serialize , Deserialize , PartialEq , Eq , PartialOrd , Ord ) ]
12+ #[ derive( Debug , Clone , Serialize , Deserialize , PartialEq , Eq , PartialOrd , Ord ) ]
713pub struct UnionType {
814 types : BTreeSet < BasicValueType > ,
915}
1016
1117impl UnionType {
18+ fn new ( ) -> Self {
19+ Self { types : BTreeSet :: new ( ) }
20+ }
21+
1222 pub fn types ( & self ) -> & BTreeSet < BasicValueType > {
1323 & self . types
1424 }
@@ -31,32 +41,56 @@ impl UnionType {
3141 }
3242 }
3343
34- pub fn unpack ( self ) -> Self {
35- self . types . into ( )
36- }
37- }
44+ fn resolve ( self ) -> Result < UnionParseResult > {
45+ if self . types ( ) . is_empty ( ) {
46+ anyhow :: bail! ( "The union is empty" ) ;
47+ }
3848
39- impl From < Vec < BasicValueType > > for UnionType {
40- fn from ( value : Vec < BasicValueType > ) -> Self {
41- let mut union = Self :: default ( ) ;
49+ if self . types ( ) . len ( ) == 1 {
50+ let mut type_tree: BTreeSet < BasicValueType > = self . into ( ) ;
51+ return Ok ( UnionParseResult :: Single ( type_tree. pop_first ( ) . unwrap ( ) ) ) ;
52+ }
4253
43- for typ in value {
54+ Ok ( UnionParseResult :: Union ( self ) )
55+ }
56+
57+ /// Move an iterable and parse it into a union type.
58+ /// If there is only one single unique type, it returns a single `BasicValueType`.
59+ pub fn parse_from < T > (
60+ input : impl IntoIterator < Item = BasicValueType , IntoIter = T > ,
61+ ) -> Result < UnionParseResult >
62+ where
63+ T : Iterator < Item = BasicValueType > ,
64+ {
65+ let mut union = Self :: new ( ) ;
66+
67+ for typ in input {
4468 union. insert ( typ) ;
4569 }
4670
47- union
71+ union. resolve ( )
4872 }
49- }
50-
51- impl From < BTreeSet < BasicValueType > > for UnionType {
52- fn from ( value : BTreeSet < BasicValueType > ) -> Self {
53- let mut union = Self :: default ( ) ;
5473
55- for typ in value {
56- union. insert ( typ) ;
74+ /// Assume the input already contains multiple unique types, panic otherwise.
75+ ///
76+ /// This method is meant for streamlining the code for test cases.
77+ /// Use `parse_from()` instead unless you know the input.
78+ pub fn coerce_from < T > (
79+ input : impl IntoIterator < Item = BasicValueType , IntoIter = T > ,
80+ ) -> Self
81+ where
82+ T : Iterator < Item = BasicValueType > ,
83+ {
84+ match Self :: parse_from ( input) {
85+ Ok ( UnionParseResult :: Union ( union) ) => union,
86+ _ => panic ! ( "Do not use `coerce_from()` for basic type lists that can possibly be one type." ) ,
5787 }
88+ }
89+ }
5890
59- union
91+ impl Into < BTreeSet < BasicValueType > > for UnionType {
92+ fn into ( self ) -> BTreeSet < BasicValueType > {
93+ self . types
6094 }
6195}
6296
0 commit comments