use crate::config::errors::ConfigError;
use crate::config::path::Path;
use crate::config::validator::ValidatorError;
use crate::derive_enum;
use schematic_types::Schematic;
use serde::{de::DeserializeOwned, Serialize};
pub struct Meta {
pub name: &'static str,
}
pub trait PartialConfig:
Clone + Default + DeserializeOwned + Schematic + Serialize + Sized
{
type Context: Default;
fn default_values(context: &Self::Context) -> Result<Option<Self>, ConfigError>;
fn env_values() -> Result<Option<Self>, ConfigError>;
fn extends_from(&self) -> Option<ExtendsFrom>;
fn finalize(self, context: &Self::Context) -> Result<Self, ConfigError>;
fn merge(&mut self, context: &Self::Context, next: Self) -> Result<(), ConfigError>;
fn validate(&self, context: &Self::Context, finalize: bool) -> Result<(), ValidatorError> {
self.validate_with_path(context, finalize, Path::default())
}
#[doc(hidden)]
fn validate_with_path(
&self,
_context: &Self::Context,
_finalize: bool,
_path: Path,
) -> Result<(), ValidatorError> {
Ok(())
}
}
pub trait Config: Sized + Schematic {
type Partial: PartialConfig;
const META: Meta;
fn from_partial(partial: Self::Partial) -> Self;
}
pub trait ConfigEnum: Sized + Schematic {
const META: Meta;
fn variants() -> Vec<Self>;
}
derive_enum!(
#[serde(untagged)]
pub enum ExtendsFrom {
String(String),
List(Vec<String>),
}
);
impl Default for ExtendsFrom {
fn default() -> Self {
Self::List(vec![])
}
}
impl Schematic for ExtendsFrom {
fn generate_schema() -> schematic_types::SchemaType {
use schematic_types::*;
let mut schema = SchemaType::union([
SchemaType::string(),
SchemaType::array(SchemaType::string()),
]);
schema.set_name("ExtendsFrom");
schema
}
}