swayipc_command_builder/
command.rs

1use super::states::{And, Chain, Filter, ForWindow, Valid};
2use std::default::Default;
3use std::fmt::Debug;
4use std::fmt::Display;
5use std::marker::PhantomData;
6
7//TODO: macro
8
9pub trait Finalize {}
10impl Finalize for () {}
11impl Finalize for ForWindow {}
12impl Finalize for Filter {}
13impl Finalize for And {}
14impl Finalize for Chain {}
15
16//FIXME: better trait name
17pub trait Chained {}
18impl Chained for () {}
19impl Chained for And {}
20impl Chained for Chain {}
21
22pub trait AddFilter {}
23impl AddFilter for () {}
24impl AddFilter for Chain {}
25
26pub struct Command<T = ()> {
27    inner: String,
28    state: PhantomData<T>,
29}
30
31impl Command {
32    pub fn new() -> Self {
33        Self {
34            inner: String::new(),
35            state: PhantomData,
36        }
37    }
38}
39
40impl Command<Valid> {
41    pub fn new_unchecked(inner: impl Into<String>) -> Self {
42        Self {
43            inner: inner.into(),
44            state: PhantomData,
45        }
46    }
47}
48
49impl<T> Command<Valid<T>> {
50    pub fn and(self) -> Command<And> {
51        self.push_char(',').transmute()
52    }
53
54    pub fn chain(self) -> Command<Chain> {
55        self.push_char(';').transmute()
56    }
57}
58
59impl<T> Command<T> {
60    pub(super) fn push_str(mut self, val: impl AsRef<str>) -> Self {
61        if !self.inner.is_empty() {
62            self.inner.push(' ');
63        }
64        self.push_str_without_space(val)
65    }
66
67    pub(super) fn push_str_without_space(mut self, val: impl AsRef<str>) -> Self {
68        self.inner.push_str(val.as_ref());
69        self
70    }
71
72    pub(super) fn push_char(mut self, ch: char) -> Self {
73        self.inner.push(ch);
74        self
75    }
76
77    pub(super) fn transmute<N>(self) -> Command<N> {
78        Command {
79            inner: self.inner,
80            state: PhantomData,
81        }
82    }
83}
84
85impl<T> Debug for Command<T> {
86    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87        Debug::fmt(&self.inner, f)
88    }
89}
90
91impl<T> Display for Command<Valid<T>> {
92    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93        Display::fmt(&self.inner, f)
94    }
95}
96
97impl<T> AsRef<str> for Command<Valid<T>> {
98    fn as_ref(&self) -> &str {
99        &self.inner
100    }
101}
102
103impl<T> From<Command<Valid<T>>> for String {
104    fn from(command: Command<Valid<T>>) -> Self {
105        command.inner
106    }
107}
108
109impl Default for Command {
110    fn default() -> Self {
111        Self::new()
112    }
113}