swayipc_command_builder/
filter.rs

1use super::states::Valid;
2use std::default::Default;
3use std::fmt::{Debug, Display};
4use std::marker::PhantomData;
5
6//TODO: document behavior on multiple fn call like `Filter::new().shell("a").shell("b")`
7
8pub struct Filter<T = ()> {
9    inner: String,
10    state: PhantomData<T>,
11}
12
13impl Filter {
14    pub fn new() -> Self {
15        Self {
16            inner: String::new(),
17            state: PhantomData,
18        }
19    }
20}
21
22impl<T> Filter<T> {
23    fn insert<N>(self, key: impl AsRef<str>, value: impl AsRef<str>) -> Filter<N> {
24        let mut inner = self.inner;
25        if inner.is_empty() {
26            inner.push('[');
27        } else {
28            inner.pop();
29            inner.push(' ');
30        }
31        inner.push_str(key.as_ref());
32        inner.push('=');
33        inner.push_str(value.as_ref());
34        inner.push(']');
35        Filter {
36            inner,
37            state: PhantomData,
38        }
39    }
40}
41
42pub trait Finalize {}
43impl Finalize for () {}
44impl Finalize for Valid {}
45
46impl<T: Finalize> Filter<T> {
47    pub fn app_id(self, value: impl AsRef<str>) -> Filter<Valid> {
48        self.insert("app_id", value)
49    }
50
51    pub fn class(self, value: impl AsRef<str>) -> Filter<Valid> {
52        self.insert("class", value)
53    }
54
55    pub fn con_id(self, value: impl AsRef<str>) -> Filter<Valid> {
56        self.insert("con_id", value)
57    }
58
59    pub fn con_mark(self, value: impl AsRef<str>) -> Filter<Valid> {
60        self.insert("con_mark", value)
61    }
62
63    pub fn floating(self, value: impl AsRef<str>) -> Filter<Valid> {
64        self.insert("floating", value)
65    }
66
67    pub fn id(self, value: impl AsRef<str>) -> Filter<Valid> {
68        self.insert("id", value)
69    }
70
71    pub fn instance(self, value: impl AsRef<str>) -> Filter<Valid> {
72        self.insert("instance", value)
73    }
74
75    pub fn pid(self, value: impl AsRef<str>) -> Filter<Valid> {
76        self.insert("pid", value)
77    }
78
79    pub fn shell(self, value: impl AsRef<str>) -> Filter<Valid> {
80        self.insert("shell", value)
81    }
82
83    pub fn tiling(self, value: impl AsRef<str>) -> Filter<Valid> {
84        self.insert("tiling", value)
85    }
86
87    pub fn title(self, value: impl AsRef<str>) -> Filter<Valid> {
88        self.insert("title", value)
89    }
90
91    pub fn urgent(self, value: impl AsRef<str>) -> Filter<Valid> {
92        self.insert("urgent", value)
93    }
94
95    pub fn window_role(self, value: impl AsRef<str>) -> Filter<Valid> {
96        self.insert("window_role", value)
97    }
98
99    pub fn window_type(self, value: impl AsRef<str>) -> Filter<Valid> {
100        self.insert("window_type", value)
101    }
102
103    pub fn workspace(self, value: impl AsRef<str>) -> Filter<Valid> {
104        self.insert("workspace", value)
105    }
106}
107
108impl<T> Debug for Filter<T> {
109    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
110        Debug::fmt(&self.inner, f)
111    }
112}
113
114impl Display for Filter<Valid> {
115    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116        Display::fmt(&self.inner, f)
117    }
118}
119
120impl AsRef<str> for Filter<Valid> {
121    fn as_ref(&self) -> &str {
122        &self.inner
123    }
124}
125
126impl From<Filter<Valid>> for String {
127    fn from(filter: Filter<Valid>) -> Self {
128        filter.inner
129    }
130}
131
132impl Default for Filter {
133    fn default() -> Self {
134        Self::new()
135    }
136}