dynamodb_expression/condition/contains.rs
1use core::fmt::{self, Write};
2
3use crate::{
4 path::Path,
5 value::{Value, ValueOrRef},
6};
7
8/// The [DynamoDB `contains` function][1]. True if the attribute specified
9/// by [`Path`] is one of the following:
10/// * A `String` that contains a particular substring.
11/// * A `Set` that contains a particular element within the set.
12/// * A `List` that contains a particular element within the list.
13///
14/// The operand must be a `String` if the attribute specified by path is a
15/// `String`. If the attribute specified by path is a `Set`, the operand
16/// must be the sets element type.
17///
18/// See also: [`Path::contains`]
19///
20/// ```
21/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
22/// use dynamodb_expression::{Num, Path};
23///
24/// // String
25/// let condition = "foo".parse::<Path>()?.contains("Quinn");
26/// assert_eq!(r#"contains(foo, "Quinn")"#, condition.to_string());
27///
28/// // Number
29/// let condition = "foo".parse::<Path>()?.contains(Num::new(42));
30/// assert_eq!(r#"contains(foo, 42)"#, condition.to_string());
31///
32/// // Binary
33/// let condition = "foo".parse::<Path>()?.contains(Vec::<u8>::from("fish"));
34/// assert_eq!(r#"contains(foo, "ZmlzaA==")"#, condition.to_string());
35/// #
36/// # Ok(())
37/// # }
38/// ```
39///
40/// [1]: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions
41#[derive(Debug, Clone, PartialEq, Eq)]
42pub struct Contains {
43 // `Path` is correct here
44 // https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Syntax
45 pub(crate) path: Path,
46 pub(crate) operand: ValueOrRef,
47}
48
49impl Contains {
50 /// Allows for manually creating a `Contains` instance.
51 ///
52 /// See also: [`Path::contains`]
53 ///
54 /// ```
55 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
56 /// use dynamodb_expression::{condition::Contains, Num, Path};
57 ///
58 /// // String
59 /// let condition = Contains::new("foo".parse::<Path>()?, "Quinn");
60 /// assert_eq!(r#"contains(foo, "Quinn")"#, condition.to_string());
61 ///
62 /// // Number
63 /// let condition = Contains::new("foo".parse::<Path>()?, Num::new(42));
64 /// assert_eq!(r#"contains(foo, 42)"#, condition.to_string());
65 ///
66 /// // Binary
67 /// let condition = Contains::new("foo".parse::<Path>()?, Vec::<u8>::from("fish"));
68 /// assert_eq!(r#"contains(foo, "ZmlzaA==")"#, condition.to_string());
69 /// #
70 /// # Ok(())
71 /// # }
72 /// ```
73 pub fn new<P, S>(path: P, operand: S) -> Self
74 where
75 P: Into<Path>,
76 S: Into<Value>,
77 {
78 Self {
79 path: path.into(),
80 operand: operand.into().into(),
81 }
82 }
83}
84
85impl fmt::Display for Contains {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 f.write_str("contains(")?;
88 self.path.fmt(f)?;
89 f.write_str(", ")?;
90 self.operand.fmt(f)?;
91 f.write_char(')')
92 }
93}