use lazy_static::lazy_static;
use std::ops::Deref;
use url::Url;
use super::File;
use crate::errors::*;
const COMPOSE_2_0_SCHEMA_STR: &str = include_str!("config_schema_v2.0.json");
const COMPOSE_2_1_SCHEMA_STR: &str = include_str!("config_schema_v2.1.json");
const COMPOSE_2_2_SCHEMA_STR: &str = include_str!("config_schema_v2.2.json");
const COMPOSE_2_3_SCHEMA_STR: &str = include_str!("config_schema_v2.3.json");
const COMPOSE_2_4_SCHEMA_STR: &str = include_str!("config_schema_v2.4.json");
fn load_schema_json(json: &'static str) -> serde_json::Value {
match serde_json::from_str(json) {
Ok(value) => value,
Err(err) => panic!("cannot parse built-in schema: {}", err),
}
}
lazy_static! {
static ref COMPOSE_2_0_SCHEMA: serde_json::Value =
load_schema_json(COMPOSE_2_0_SCHEMA_STR);
static ref COMPOSE_2_1_SCHEMA: serde_json::Value =
load_schema_json(COMPOSE_2_1_SCHEMA_STR);
static ref COMPOSE_2_2_SCHEMA: serde_json::Value =
load_schema_json(COMPOSE_2_2_SCHEMA_STR);
static ref COMPOSE_2_3_SCHEMA: serde_json::Value =
load_schema_json(COMPOSE_2_3_SCHEMA_STR);
static ref COMPOSE_2_4_SCHEMA: serde_json::Value =
load_schema_json(COMPOSE_2_4_SCHEMA_STR);
}
pub fn validate_file(file: &File) -> Result<()> {
let schema_value = match &file.version[..] {
"2" => COMPOSE_2_0_SCHEMA.deref(),
"2.1" => COMPOSE_2_1_SCHEMA.deref(),
"2.2" => COMPOSE_2_2_SCHEMA.deref(),
"2.3" => COMPOSE_2_3_SCHEMA.deref(),
"2.4" => COMPOSE_2_4_SCHEMA.deref(),
vers => return Err(Error::UnsupportedVersion(vers.to_owned())),
};
let mut scope = valico::json_schema::Scope::new();
let id = Url::parse("http://example.com/config_schema.json")
.expect("internal schema URL should be valid");
let schema_result =
scope.compile_and_return_with_id(&id, schema_value.clone(), false);
let schema = match schema_result {
Ok(schema) => schema,
Err(err) => panic!("cannot parse built-in schema: {:?}", err),
};
let value = serde_json::to_value(&file).map_err(Error::validation_failed)?;
let validation_state = schema.validate(&value);
if validation_state.is_strictly_valid() {
Ok(())
} else {
Err(Error::validation_failed(Error::does_not_conform_to_schema(
validation_state,
)))
}
}