1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
6pub struct Range<T> {
7 pub start: Option<T>,
8 pub end: Option<T>,
9}
10
11impl<T> Range<T> {
12 pub const fn unbounded() -> Self {
13 Range {
14 start: None,
15 end: None,
16 }
17 }
18
19 pub fn try_map<U, E, F: Fn(T) -> Result<U, E>>(self, f: F) -> Result<Range<U>, E> {
20 Ok(Range {
21 start: self.start.map(&f).transpose()?,
22 end: self.end.map(f).transpose()?,
23 })
24 }
25
26 pub fn map<U, F: Fn(T) -> U>(self, f: F) -> Range<U> {
27 Range {
28 start: self.start.map(&f),
29 end: self.end.map(f),
30 }
31 }
32}
33
34#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
35pub enum InterpolateItem<T> {
36 String(String),
37 Expr {
38 expr: Box<T>,
39 format: Option<String>,
40 },
41}
42
43impl<T> InterpolateItem<T> {
44 pub fn map<U, F: Fn(T) -> U>(self, f: F) -> InterpolateItem<U> {
45 match self {
46 Self::String(s) => InterpolateItem::String(s),
47 Self::Expr { expr, format } => InterpolateItem::Expr {
48 expr: Box::new(f(*expr)),
49 format,
50 },
51 }
52 }
53
54 pub fn try_map<U, E, F: Fn(T) -> Result<U, E>>(self, f: F) -> Result<InterpolateItem<U>, E> {
55 Ok(match self {
56 Self::String(s) => InterpolateItem::String(s),
57 Self::Expr { expr, format } => InterpolateItem::Expr {
58 expr: Box::new(f(*expr)?),
59 format,
60 },
61 })
62 }
63}
64
65#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
66pub struct SwitchCase<T> {
67 pub condition: T,
68 pub value: T,
69}