1use crate::types::decode::Decode;
2use crate::types::encode::{Encode, IsNull};
3use crate::value::{PgValue, PgValueFormat};
4use rbdc::Error;
5use rbs::Value;
6
7#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Eq, PartialEq)]
12pub struct TsQuery(pub String);
13
14impl From<String> for TsQuery {
15 fn from(value: String) -> Self {
16 Self(value)
17 }
18}
19
20impl From<&str> for TsQuery {
21 fn from(value: &str) -> Self {
22 Self(value.to_string())
23 }
24}
25
26impl From<TsQuery> for Value {
27 fn from(arg: TsQuery) -> Self {
28 rbs::Value::Ext("tsquery", Box::new(rbs::Value::String(arg.0)))
29 }
30}
31
32impl std::fmt::Display for TsQuery {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 write!(f, "{}", self.0)
35 }
36}
37
38impl Decode for TsQuery {
39 fn decode(value: PgValue) -> Result<Self, Error> {
40 Ok(match value.format() {
41 PgValueFormat::Binary => {
42 let bytes = value.as_bytes()?;
46 Self(String::from_utf8_lossy(bytes).to_string())
47 }
48 PgValueFormat::Text => {
49 let s = value.as_str()?;
50 Self(s.to_string())
51 }
52 })
53 }
54}
55
56impl Encode for TsQuery {
57 fn encode(self, _buf: &mut crate::arguments::PgArgumentBuffer) -> Result<IsNull, Error> {
58 Err(Error::from(
61 "TsQuery encoding not supported. Use PostgreSQL's to_tsquery() function in your query instead."
62 ))
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69 use crate::types::decode::Decode;
70 use crate::value::{PgValue, PgValueFormat};
71
72 #[test]
73 fn test_display() {
74 let tsquery = TsQuery("hello & world".to_string());
75 assert_eq!(format!("{}", tsquery), "hello & world");
76 }
77
78 #[test]
79 fn test_from_str() {
80 let tsquery = TsQuery::from("search & query");
81 assert_eq!(tsquery.0, "search & query");
82 }
83
84 #[test]
85 fn test_decode_text() {
86 let s = "hello & world";
87 let result: TsQuery = Decode::decode(PgValue {
88 value: Some(s.as_bytes().to_vec()),
89 type_info: crate::type_info::PgTypeInfo::UNKNOWN,
90 format: PgValueFormat::Text,
91 timezone_sec: None,
92 }).unwrap();
93 assert_eq!(result.0, "hello & world");
94 }
95
96 #[test]
97 fn test_from_value() {
98 let tsquery = TsQuery("test".to_string());
99 let value: rbs::Value = tsquery.into();
100 match value {
101 rbs::Value::Ext(type_name, boxed) => {
102 assert_eq!(type_name, "tsquery");
103 if let rbs::Value::String(s) = *boxed {
104 assert_eq!(s, "test");
105 } else {
106 panic!("Expected String value");
107 }
108 }
109 _ => panic!("Expected Ext variant"),
110 }
111 }
112}