use crate::validation::{rules, IntoValidationReport, Validate, ValidationReport};
use acorn_core::prelude::alloc::{String, ToString};
use acorn_core::validation::ValidationError;
use bon::Builder;
use schemars::{JsonSchema, Schema, SchemaGenerator};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_trim::{option_string_trim, string_trim};
use serde_with::skip_serializing_none;
pub mod cff;
pub mod ckan;
pub mod crosswalk;
pub mod datacite;
#[cfg(feature = "std")]
pub mod dcat;
#[cfg(feature = "std")]
pub mod dublin_core;
#[cfg(feature = "std")]
pub mod huwise;
pub mod invenio;
pub mod ocp;
#[cfg(all(test, feature = "std"))]
mod tests;
pub mod text;
pub mod zon;
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, Ord, PartialEq, PartialOrd, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum ClaimAssessment {
Declared,
Inferred,
Verified,
}
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum ConformanceResult {
Fail,
NotTested,
Partial,
Pass,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ContributionKind {
DesignFiles,
Other(String),
ReferenceArchitecture,
RequirementsDocument,
Software,
Specification,
TestedConfiguration,
WhitePaper,
}
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, Ord, PartialEq, PartialOrd, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum StandardsRelationship {
BasedOn,
ConformsTo,
Implements,
References,
TestedAgainst,
}
#[skip_serializing_none]
#[derive(Builder, Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize, Validate)]
#[builder(start_fn = init, on(String, into))]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct StandardReference {
#[validate(nonempty)]
#[serde(deserialize_with = "string_trim")]
pub authority: String,
#[validate(nonempty)]
#[serde(deserialize_with = "string_trim")]
pub identifier: String,
#[validate(nonempty)]
#[serde(default, deserialize_with = "option_string_trim")]
pub title: Option<String>,
#[validate(nonempty)]
#[serde(default, deserialize_with = "option_string_trim")]
pub version: Option<String>,
#[validate(uri)]
#[serde(deserialize_with = "string_trim")]
pub canonical_uri: String,
}
#[skip_serializing_none]
#[derive(Builder, Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize, Validate)]
#[builder(start_fn = init, on(String, into))]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
#[validate(schema(function = "StandardsClaim::is_valid", skip_on_field_errors = false))]
pub struct StandardsClaim {
#[validate(nested)]
pub standard: StandardReference,
pub relationship: StandardsRelationship,
pub assessment: ClaimAssessment,
#[validate(uri)]
#[serde(default, deserialize_with = "option_string_trim")]
pub evidence_uri: Option<String>,
}
impl StandardsClaim {
fn is_valid(&self, _context: &()) -> Result<(), ValidationReport> {
match (&self.assessment, &self.evidence_uri) {
| (ClaimAssessment::Verified, None) => ValidationError::new("evidence_required")
.with_message("Verified standards claims require evidenceUri")
.into_report("evidence_uri")
.finish(),
| _ => Ok(()),
}
}
}
impl<'de> Deserialize<'de> for ContributionKind {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
String::deserialize(deserializer).map(Self::from)
}
}
impl From<String> for ContributionKind {
fn from(value: String) -> Self {
let value = value.trim().to_string();
match value.as_str() {
| "designFiles" | "Design Files" => Self::DesignFiles,
| "referenceArchitecture" | "Reference Architecture" => Self::ReferenceArchitecture,
| "requirementsDocument" | "Requirements Document" => Self::RequirementsDocument,
| "software" | "Software" => Self::Software,
| "specification" | "Specification" => Self::Specification,
| "testedConfiguration" | "Tested Configuration" => Self::TestedConfiguration,
| "whitePaper" | "White Paper" => Self::WhitePaper,
| _ => Self::Other(value),
}
}
}
impl JsonSchema for ContributionKind {
fn schema_name() -> alloc::borrow::Cow<'static, str> {
"ContributionKind".into()
}
fn json_schema(generator: &mut SchemaGenerator) -> Schema {
String::json_schema(generator)
}
}
impl Serialize for ContributionKind {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(match self {
| Self::DesignFiles => "designFiles",
| Self::Other(value) => value,
| Self::ReferenceArchitecture => "referenceArchitecture",
| Self::RequirementsDocument => "requirementsDocument",
| Self::Software => "software",
| Self::Specification => "specification",
| Self::TestedConfiguration => "testedConfiguration",
| Self::WhitePaper => "whitePaper",
})
}
}
impl Validate for ContributionKind {
fn validate(&self) -> Result<(), ValidationReport> {
match self {
| Self::Other(value) => rules::nonempty(value).map_err(|error| error.into_report("")),
| _ => Ok(()),
}
}
}