plex_api/myplex/sharing/
filter.rs1use serde::{
2 de::{Deserializer, Visitor},
3 Deserialize, Serialize,
4};
5use std::{
6 fmt::{Display, Formatter, Result as FmtResult},
7 result::Result as StdResult,
8};
9
10#[derive(Default, Debug, Clone)]
11pub struct SharingFilter {
12 pub content_rating: Vec<String>,
13 pub exclude_content_rating: Vec<String>,
14 pub label: Vec<String>,
15 pub exclude_label: Vec<String>,
16}
17
18impl<'de> Deserialize<'de> for SharingFilter {
19 fn deserialize<D>(deserializer: D) -> StdResult<Self, D::Error>
20 where
21 D: Deserializer<'de>,
22 {
23 struct V;
24
25 impl<'de> Visitor<'de> for V {
26 type Value = SharingFilter;
27
28 fn expecting(&self, formatter: &mut Formatter) -> FmtResult {
29 formatter.write_str("valid plex filter string")
30 }
31
32 fn visit_str<E>(self, value: &str) -> StdResult<SharingFilter, E>
33 where
34 E: ::serde::de::Error,
35 {
36 let mut ret = SharingFilter::default();
37
38 if value.is_empty() {
39 return Ok(ret);
40 }
41
42 for filter in value.split('|') {
43 let decoded_values =
44 serde_urlencoded::from_str::<Vec<(String, String)>>(filter);
45 if let Ok(decoded_values) = decoded_values {
46 for pairs in decoded_values {
47 match pairs.0.as_str() {
48 "contentRating" => {
49 ret.content_rating =
50 pairs.1.split(',').map(|v| v.to_owned()).collect()
51 }
52 "contentRating!" => {
53 ret.exclude_content_rating =
54 pairs.1.split(',').map(|v| v.to_owned()).collect()
55 }
56 "label" => {
57 ret.label = pairs.1.split(',').map(|v| v.to_owned()).collect()
58 }
59 "label!" => {
60 ret.exclude_label =
61 pairs.1.split(',').map(|v| v.to_owned()).collect()
62 }
63 _ => {
64 return Err(::serde::de::Error::invalid_value(
65 ::serde::de::Unexpected::Str(value),
66 &self,
67 ));
68 }
69 }
70 }
71 } else {
72 return Err(::serde::de::Error::invalid_value(
73 ::serde::de::Unexpected::Str(value),
74 &self,
75 ));
76 }
77 }
78
79 Ok(ret)
80 }
81 }
82
83 deserializer.deserialize_str(V)
84 }
85}
86
87impl Serialize for SharingFilter {
88 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
89 where
90 S: ::serde::ser::Serializer,
91 {
92 serializer.serialize_str(&self.to_string())
93 }
94}
95
96impl Display for SharingFilter {
97 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
98 let mut ret: Vec<String> = vec![];
99
100 if !self.content_rating.is_empty() {
101 ret.push(format!("contentRating={}", self.content_rating.join("%2C")))
102 }
103
104 if !self.exclude_content_rating.is_empty() {
105 ret.push(format!(
106 "contentRating!={}",
107 self.exclude_content_rating.join("%2C")
108 ))
109 }
110
111 if !self.label.is_empty() {
112 ret.push(format!("label={}", self.label.join("%2C")))
113 }
114
115 if !self.exclude_label.is_empty() {
116 ret.push(format!("label!={}", self.exclude_label.join("%2C")))
117 }
118
119 write!(f, "{}", ret.join("|"))
120 }
121}