1pub mod milestone;
4pub mod policy;
5pub mod service;
6pub mod system_conf;
7
8pub use milestone::Milestone;
9pub use policy::Policy;
10pub use service::Service;
11pub use system_conf::SystemConf;
12
13use crate::prelude::*;
14use std::{borrow::Cow, sync::Arc};
15
16pub trait Validate {
17 fn validate(&self) -> Result<(), ReadError>;
18}
19
20pub trait Named {
21 fn set_name(&mut self, name: String);
22}
23
24pub fn merge(doc: &mut toml::Value, patch: &toml::Value) {
25 if !patch.is_table() {
26 *doc = patch.clone();
27 return;
28 }
29
30 if !doc.is_table() {
31 *doc = toml::Value::Table(toml::Table::new());
32 }
33 let map = doc.as_table_mut().unwrap();
34 for (key, value) in patch.as_table().unwrap() {
35 if value.is_table() && value.as_table().unwrap().is_empty() {
36 map.remove(key.as_str());
37 } else {
38 merge(
39 map.entry(key.as_str())
40 .or_insert(toml::Value::Table(toml::Table::new())),
41 value,
42 );
43 }
44 }
45}
46
47#[derive(Debug, Clone, thiserror::Error)]
48pub enum ReadError {
49 #[error("{0}")]
50 Io(Arc<std::io::Error>),
51
52 #[error("{0}")]
53 Parse(String),
54
55 #[error("{0}")]
56 Validation(Cow<'static, str>),
57}
58impl From<std::io::Error> for ReadError {
59 fn from(value: std::io::Error) -> Self {
60 Self::Io(value.into())
61 }
62}
63impl From<toml::de::Error> for ReadError {
64 fn from(value: toml::de::Error) -> Self {
65 Self::Parse(value.message().to_owned())
66 }
67}
68impl From<&'static str> for ReadError {
69 fn from(value: &'static str) -> Self {
70 Self::Validation(value.into())
71 }
72}
73impl From<String> for ReadError {
74 fn from(value: String) -> Self {
75 Self::Validation(value.into())
76 }
77}
78impl From<std::io::ErrorKind> for ReadError {
79 fn from(value: std::io::ErrorKind) -> Self {
80 Self::from(std::io::Error::from(value))
81 }
82}
83impl IntoApiError for ReadError {
84 fn into_api_error(self) -> crate::Error {
85 match self {
86 Self::Io(err) => match err.kind() {
87 std::io::ErrorKind::NotFound => crate::Error::NotFound,
88 _ => crate::Error::Io {
89 message: err.to_string(),
90 },
91 },
92 Self::Parse(x) => crate::Error::BadObject { message: x.into() },
93 Self::Validation(x) => crate::Error::BadObject { message: x },
94 }
95 }
96}