swayipc_command_builder/
command.rs1use super::states::{And, Chain, Filter, ForWindow, Valid};
2use std::default::Default;
3use std::fmt::Debug;
4use std::fmt::Display;
5use std::marker::PhantomData;
6
7pub trait Finalize {}
10impl Finalize for () {}
11impl Finalize for ForWindow {}
12impl Finalize for Filter {}
13impl Finalize for And {}
14impl Finalize for Chain {}
15
16pub 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}