git_checks_config/
registry.rs1use std::error::Error;
10
11use erased_serde::Deserializer;
12use git_checks_core::{BranchCheck, Check, TopicCheck};
13use serde::de::DeserializeOwned;
14
15pub trait IntoCheck: DeserializeOwned {
20 type Check;
22
23 fn into_check(self) -> Self::Check;
25}
26
27type CtorResult<T> = Result<T, Box<dyn Error + Send + Sync>>;
28
29#[doc(hidden)]
33pub struct CheckCtor<T> {
34 pub f: fn(&mut dyn Deserializer) -> CtorResult<T>,
35}
36
37#[doc(hidden)]
39pub trait CheckConfig {
40 type CheckTrait: ?Sized;
41}
42
43pub struct BranchCheckConfig {
47 name: &'static str,
48 ctor: CheckCtor<DynBranchCheck>,
49}
50
51#[doc(hidden)]
53pub struct DynBranchCheck(Box<dyn BranchCheck>);
54
55impl BranchCheckConfig {
56 #[doc(hidden)]
58 pub const fn new(name: &'static str, ctor: CheckCtor<DynBranchCheck>) -> Self {
59 Self {
60 name,
61 ctor,
62 }
63 }
64
65 pub fn name(&self) -> &'static str {
67 self.name
68 }
69
70 pub fn create(&self, conf: &mut dyn Deserializer) -> CtorResult<Box<dyn BranchCheck>> {
72 Ok((self.ctor.f)(conf)?.0)
73 }
74
75 #[doc(hidden)]
77 pub fn ctor<C>(conf: &mut dyn Deserializer) -> CtorResult<DynBranchCheck>
78 where
79 C: IntoCheck,
80 C::Check: BranchCheck + 'static,
81 {
82 erased_serde::deserialize(conf)
83 .map(|c: C| DynBranchCheck(Box::new(c.into_check())))
84 .map_err(Into::into)
85 }
86}
87
88impl CheckConfig for BranchCheckConfig {
89 type CheckTrait = dyn BranchCheck;
90}
91
92pub struct CommitCheckConfig {
96 name: &'static str,
97 ctor: CheckCtor<DynCheck>,
98}
99
100#[doc(hidden)]
102pub struct DynCheck(Box<dyn Check>);
103
104impl CommitCheckConfig {
105 #[doc(hidden)]
107 pub const fn new(name: &'static str, ctor: CheckCtor<DynCheck>) -> Self {
108 Self {
109 name,
110 ctor,
111 }
112 }
113
114 pub fn name(&self) -> &'static str {
116 self.name
117 }
118
119 pub fn create(&self, conf: &mut dyn Deserializer) -> CtorResult<Box<dyn Check>> {
121 Ok((self.ctor.f)(conf)?.0)
122 }
123
124 #[doc(hidden)]
126 pub fn ctor<C>(conf: &mut dyn Deserializer) -> CtorResult<DynCheck>
127 where
128 C: IntoCheck,
129 C::Check: Check + 'static,
130 {
131 erased_serde::deserialize(conf)
132 .map(|c: C| DynCheck(Box::new(c.into_check())))
133 .map_err(Into::into)
134 }
135}
136
137impl CheckConfig for CommitCheckConfig {
138 type CheckTrait = dyn Check;
139}
140
141pub struct TopicCheckConfig {
145 name: &'static str,
146 ctor: CheckCtor<DynTopicCheck>,
147}
148
149#[doc(hidden)]
151pub struct DynTopicCheck(Box<dyn TopicCheck>);
152
153impl TopicCheckConfig {
154 #[doc(hidden)]
156 pub const fn new(name: &'static str, ctor: CheckCtor<DynTopicCheck>) -> Self {
157 Self {
158 name,
159 ctor,
160 }
161 }
162
163 pub fn name(&self) -> &'static str {
165 self.name
166 }
167
168 pub fn create(&self, conf: &mut dyn Deserializer) -> CtorResult<Box<dyn TopicCheck>> {
170 Ok((self.ctor.f)(conf)?.0)
171 }
172
173 #[doc(hidden)]
175 pub fn ctor<C>(conf: &mut dyn Deserializer) -> CtorResult<DynTopicCheck>
176 where
177 C: IntoCheck,
178 C::Check: TopicCheck + 'static,
179 {
180 erased_serde::deserialize(conf)
181 .map(|c: C| DynTopicCheck(Box::new(c.into_check())))
182 .map_err(Into::into)
183 }
184}
185
186impl CheckConfig for TopicCheckConfig {
187 type CheckTrait = dyn TopicCheck;
188}
189
190inventory::collect!(BranchCheckConfig);
191inventory::collect!(CommitCheckConfig);
192inventory::collect!(TopicCheckConfig);