partiql_value/
bindings.rs

1use crate::datum::OwnedFieldView;
2use crate::{PairsIntoIter, PairsIter, Value};
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5use std::borrow::Cow;
6use std::iter::Once;
7use unicase::UniCase;
8
9#[derive(Clone, Hash, Debug, Eq, PartialEq)]
10#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11pub enum BindingsName<'s> {
12    CaseSensitive(Cow<'s, str>),
13    CaseInsensitive(Cow<'s, str>),
14}
15
16impl<'s> BindingsName<'s> {
17    pub fn matcher(&'s self) -> BindingsMatcher<'s> {
18        BindingsMatcher::from(self)
19    }
20}
21
22#[derive(Clone, Hash, Debug, Eq, PartialEq)]
23pub enum BindingsMatcher<'s> {
24    CaseSensitive(&'s str),
25    CaseInsensitive(UniCase<&'s str>),
26}
27
28impl<'s> BindingsMatcher<'s> {
29    pub fn matches(&'s self, candidate: &str) -> bool {
30        match self {
31            BindingsMatcher::CaseSensitive(target) => *target == candidate,
32            BindingsMatcher::CaseInsensitive(target) => *target == UniCase::new(candidate),
33        }
34    }
35}
36
37impl<'s> From<&'s BindingsName<'s>> for BindingsMatcher<'s> {
38    fn from(name: &'s BindingsName<'_>) -> Self {
39        match name {
40            BindingsName::CaseSensitive(s) => BindingsMatcher::CaseSensitive(s.as_ref()),
41            BindingsName::CaseInsensitive(s) => {
42                BindingsMatcher::CaseInsensitive(UniCase::new(s.as_ref()))
43            }
44        }
45    }
46}
47
48pub enum BindingIter<'a> {
49    Tuple(PairsIter<'a>),
50    Dynamic(Box<dyn Iterator<Item = (Option<&'a str>, &'a Value)> + 'a>),
51    Single(Once<&'a Value>),
52    Empty,
53}
54
55impl<'a> Iterator for BindingIter<'a> {
56    type Item = (Option<&'a str>, &'a Value);
57
58    #[inline]
59    fn next(&mut self) -> Option<Self::Item> {
60        match self {
61            BindingIter::Tuple(t) => t.next().map(|(k, v)| (Some(k.as_str()), v)),
62            BindingIter::Single(single) => single.next().map(|v| (None, v)),
63            BindingIter::Empty => None,
64            BindingIter::Dynamic(d) => d.next(),
65        }
66    }
67
68    #[inline]
69    fn size_hint(&self) -> (usize, Option<usize>) {
70        match self {
71            BindingIter::Tuple(t) => t.size_hint(),
72            BindingIter::Single(_single) => (1, Some(1)),
73            BindingIter::Empty => (0, Some(0)),
74            BindingIter::Dynamic(d) => d.size_hint(),
75        }
76    }
77}
78
79pub enum BindingIntoIter {
80    Tuple(PairsIntoIter),
81    Single(Once<Value>),
82    Empty,
83    DynTuple(Box<dyn Iterator<Item = OwnedFieldView<Value>>>),
84}
85
86impl Iterator for BindingIntoIter {
87    type Item = (Option<String>, Value);
88
89    #[inline]
90    fn next(&mut self) -> Option<Self::Item> {
91        match self {
92            BindingIntoIter::Tuple(t) => t.next().map(|(k, v)| (Some(k), v)),
93            BindingIntoIter::Single(single) => single.next().map(|v| (None, v)),
94            BindingIntoIter::Empty => None,
95            BindingIntoIter::DynTuple(d) => d.next().map(|f| (Some(f.name), f.value)),
96        }
97    }
98
99    #[inline]
100    fn size_hint(&self) -> (usize, Option<usize>) {
101        match self {
102            BindingIntoIter::Tuple(t) => t.size_hint(),
103            BindingIntoIter::Single(_single) => (1, Some(1)),
104            BindingIntoIter::Empty => (0, Some(0)),
105            BindingIntoIter::DynTuple(d) => d.size_hint(),
106        }
107    }
108}