Skip to main content

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