1use std::collections::HashMap;
2
3use super::key::Key;
4
5pub struct Locale<'a>(pub &'a str);
7pub struct DefaultKey<T>(pub T);
9pub struct Var<T, U>(pub T, pub U);
11pub struct Count(pub i32);
13
14pub trait OptsPart<'a> {
15 fn add_to(self, opts: Opts<'a>) -> Opts<'a>;
16}
17
18impl<'a> OptsPart<'a> for Locale<'a> {
19 fn add_to(self, opts: Opts<'a>) -> Opts<'a> {
20 opts.locale(self.0)
21 }
22}
23
24impl<'a, T> OptsPart<'a> for DefaultKey<T>
25where
26 T: Into<Key<'a>>,
27{
28 fn add_to(self, opts: Opts<'a>) -> Opts<'a> {
29 opts.default_key(self.0.into())
30 }
31}
32
33impl<'a, T, U> OptsPart<'a> for Var<T, U>
34where
35 T: Into<String>,
36 U: std::fmt::Display,
37{
38 fn add_to(self, opts: Opts<'a>) -> Opts<'a> {
39 opts.var(self.0, self.1)
40 }
41}
42
43impl<'a> OptsPart<'a> for Count {
44 fn add_to(self, opts: Opts<'a>) -> Opts<'a> {
45 opts.count(self.0)
46 }
47}
48
49impl<'a, T> From<T> for Opts<'a>
50where
51 T: OptsPart<'a>,
52{
53 fn from(t: T) -> Self {
54 t.add_to(Opts::default())
55 }
56}
57
58impl<'a, T> OptsPart<'a> for (T,)
59where
60 T: OptsPart<'a>,
61{
62 fn add_to(self, opts: Opts<'a>) -> Opts<'a> {
63 self.0.add_to(opts)
64 }
65}
66
67impl<'a, T, U> OptsPart<'a> for (T, U)
68where
69 T: OptsPart<'a>,
70 U: OptsPart<'a>,
71{
72 fn add_to(self, opts: Opts<'a>) -> Opts<'a> {
73 self.1.add_to(self.0.add_to(opts))
74 }
75}
76
77impl<'a, T, U, V> OptsPart<'a> for (T, U, V)
78where
79 T: OptsPart<'a>,
80 U: OptsPart<'a>,
81 U: OptsPart<'a>,
82 V: OptsPart<'a>,
83{
84 fn add_to(self, opts: Opts<'a>) -> Opts<'a> {
85 self.2.add_to(self.1.add_to(self.0.add_to(opts)))
86 }
87}
88
89impl<'a, T, U, V, W> OptsPart<'a> for (T, U, V, W)
90where
91 T: OptsPart<'a>,
92 U: OptsPart<'a>,
93 U: OptsPart<'a>,
94 V: OptsPart<'a>,
95 W: OptsPart<'a>,
96{
97 fn add_to(self, opts: Opts<'a>) -> Opts<'a> {
98 self.3
99 .add_to(self.2.add_to(self.1.add_to(self.0.add_to(opts))))
100 }
101}
102
103#[derive(Default)]
105pub struct Opts<'a> {
106 pub(crate) default_key: Option<Key<'a>>,
107 pub(crate) vars: Option<HashMap<String, String>>,
108 pub(crate) locale: Option<&'a str>,
109 pub(crate) count: Option<i32>,
110}
111
112impl<'a> Opts<'a> {
113 pub fn default_key<I: Into<Key<'a>>>(mut self, default_key: I) -> Self {
115 self.default_key = Some(default_key.into());
116 self
117 }
118
119 pub fn locale(mut self, locale: &'a str) -> Self {
121 self.locale = Some(locale);
122 self
123 }
124
125 pub fn var<I: Into<String>, J: std::fmt::Display>(mut self, key: I, value: J) -> Self {
127 let mut vars = self.vars.take().unwrap_or_else(HashMap::new);
128 vars.insert(key.into(), value.to_string());
129 self.vars = Some(vars);
130 self
131 }
132
133 pub fn count(mut self, count: i32) -> Self {
137 self.count = Some(count);
138 self.var("count", count)
139 }
140}
141
142impl<'a> From<Option<Opts<'a>>> for Opts<'a> {
143 fn from(t: Option<Opts<'a>>) -> Self {
144 t.unwrap_or_else(Opts::default)
145 }
146}
147
148impl<'a> From<()> for Opts<'a> {
149 fn from(_: ()) -> Self {
150 Opts::default()
151 }
152}