use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub enum BmopfSchemaVersion {
Bmopf010,
#[default]
Bmopf020,
}
const SCHEMA_ID_010: &str = "https://raw.githubusercontent.com/distribution-system-opt/dsopt-schema/main/schema/bmopf/0.1.0/bmopf.schema.json";
const SCHEMA_ID_020: &str = "https://raw.githubusercontent.com/distribution-system-opt/dsopt-schema/main/schema/bmopf/0.2.0/bmopf.schema.json";
pub const BMOPF_PROPOSAL_COMMIT: &str = "664b494f2ee31ee76f8f78e7852cdb1f1c9a8e7d";
pub const BMOPF_PROPOSAL_SHA256: &str =
"74d6c6de3637d52e42a26c4cb0584f51df70d69f360b236cf5e23afaf7669462";
pub const BMOPF_PROPOSAL_URL: &str = "https://raw.githubusercontent.com/distribution-system-opt/dsopt-schema/664b494f2ee31ee76f8f78e7852cdb1f1c9a8e7d/schema/bmopf/0.2.0/bmopf.schema.json";
const ARCHIVE_URL_010: &str = "https://raw.githubusercontent.com/eigenergy/powerio/5234df55cd13ad31455697cffbdc16ca50662667/powerio-dist/schemas/bmopf/0.1.0/bmopf.schema.json";
const ARCHIVE_URL_020: &str = "https://raw.githubusercontent.com/eigenergy/powerio/5234df55cd13ad31455697cffbdc16ca50662667/powerio-dist/schemas/bmopf/0.2.0/bmopf.schema.json";
impl BmopfSchemaVersion {
#[must_use]
pub const fn version(self) -> &'static str {
match self {
Self::Bmopf010 => "0.1.0",
Self::Bmopf020 => "0.2.0",
}
}
#[must_use]
pub const fn schema_id(self) -> &'static str {
match self {
Self::Bmopf010 => SCHEMA_ID_010,
Self::Bmopf020 => SCHEMA_ID_020,
}
}
#[must_use]
pub const fn retrieval_url(self) -> &'static str {
match self {
Self::Bmopf010 => ARCHIVE_URL_010,
Self::Bmopf020 => ARCHIVE_URL_020,
}
}
#[must_use]
pub fn from_schema_id(id: &str) -> Option<Self> {
for candidate in [Self::Bmopf010, Self::Bmopf020] {
if id == candidate.schema_id() || id.contains(&format!("/{}/", candidate.version())) {
return Some(candidate);
}
}
if id.contains("bmopf-report") || id.contains("draft_bmopf_schema") {
return Some(Self::Bmopf010);
}
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_default_output_version_is_the_one_that_states_every_class() {
assert_eq!(BmopfSchemaVersion::default(), BmopfSchemaVersion::Bmopf020);
assert_eq!(BmopfSchemaVersion::default().version(), "0.2.0");
}
#[test]
fn a_version_resolves_from_its_own_schema_id() {
for expected in [BmopfSchemaVersion::Bmopf010, BmopfSchemaVersion::Bmopf020] {
assert_eq!(
BmopfSchemaVersion::from_schema_id(expected.schema_id()),
Some(expected)
);
}
}
#[test]
fn the_draft_schema_locations_resolve_to_the_version_that_repository_held() {
for id in [
"https://github.com/frederikgeth/bmopf-report/draft_schema_and_networks",
"https://raw.githubusercontent.com/frederikgeth/bmopf-report/main/draft_schema_and_networks/draft_bmopf_schema.json",
] {
assert_eq!(
BmopfSchemaVersion::from_schema_id(id),
Some(BmopfSchemaVersion::Bmopf010),
"{id}"
);
}
}
#[test]
fn a_schema_location_naming_no_version_resolves_to_none() {
assert_eq!(BmopfSchemaVersion::from_schema_id(""), None);
assert_eq!(
BmopfSchemaVersion::from_schema_id("https://example.org/bmopf/schema/v1/bmopf.json"),
None
);
}
#[test]
fn a_version_resolves_from_a_relocated_schema_of_the_same_version() {
assert_eq!(
BmopfSchemaVersion::from_schema_id(
"file:///cases/schema/bmopf/0.2.0/bmopf.schema.json"
),
Some(BmopfSchemaVersion::Bmopf020)
);
}
}