use std::collections::BTreeSet;
use std::path::Path;
use std::time::Duration;
use serde_json::Value as Json;
use shep_core::dogs::manifest::Serves;
use shep_core::paths::ShepPaths;
use crate::commands::dogs::{DogSchema, ManifestRead, VERSION_BUDGET, ask_schema, read_manifest};
use crate::commands::shep_toml::ShepToml;
use crate::dog::{builtin_manifest, builtin_schema};
use crate::dog_settings::standard::Standard;
pub(super) fn known_dogs(paths: &ShepPaths) -> BTreeSet<String> {
let from_file = ShepToml::read_only(&paths.daemon_config)
.map(|doc| {
doc.adopted_dog_names()
.into_iter()
.chain(doc.enabled_dog_names())
.collect::<Vec<_>>()
})
.unwrap_or_default();
crate::dog::BUILT_IN_DOGS
.iter()
.map(|name| (*name).to_string())
.chain(from_file)
.collect()
}
pub(super) fn dog_schema(name: &str, paths: &ShepPaths) -> Option<Json> {
dog_schema_serving(name, paths).map(|(schema, _)| schema)
}
pub(super) fn dog_schema_serving(name: &str, paths: &ShepPaths) -> Option<(Json, Serves)> {
if let Some(answer) = builtin_schema_serving(name) {
return Some(answer);
}
let adopted = ShepToml::read_only(&paths.daemon_config)
.ok()
.and_then(|doc| doc.adopted_dog_path(name));
asked_schema_serving(&adopted?, &paths.home, name, VERSION_BUDGET)
}
pub(crate) fn builtin_schema_serving(name: &str) -> Option<(Json, Serves)> {
let schema = builtin_schema(name)?;
let serves = builtin_manifest(name).map_or(Serves::OptedIn, |manifest| manifest.serves);
Some((schema, serves))
}
pub(crate) fn asked_schema_serving(
path: &Path,
home: &Path,
name: &str,
budget: Duration,
) -> Option<(Json, Serves)> {
if let Ok(ManifestRead::Read(manifest)) = read_manifest(path, home, name, budget) {
let serves = manifest.serves;
return manifest.settings.map(|schema| (schema, serves));
}
match ask_schema(path, home, name, budget) {
DogSchema::Published(schema) => Some((schema, Serves::OptedIn)),
DogSchema::Silent | DogSchema::Unreadable => None,
}
}
pub(crate) fn dog_standard(name: &str, paths: &ShepPaths) -> Option<(Json, Standard)> {
let (schema, serves) = dog_schema_serving(name, paths)?;
let standard = Standard::recognise(&schema, serves)?;
Some((schema, standard))
}