mod base_schema;
#[cfg(feature = "bench-support")]
pub mod bench_support;
mod condition_encoding;
mod emission_plan;
mod emission_policy;
mod emission_report;
mod foreign_schema;
mod merge;
mod overlay_lowering;
mod path_resolver;
mod path_schema;
mod program_wrapper;
mod provider_definitions;
mod provider_requirement_synthesis;
mod provider_schema;
mod quoted_serialization;
pub mod required_inference;
mod resolve_policy;
mod schema_model;
mod schema_node;
mod schema_tree;
mod values_yaml;
use std::collections::{BTreeMap, BTreeSet};
use helm_schema_core::{ContractSchemaSignals, ResourceSchemaOracle};
use serde_json::Value;
use serde_yaml::Value as YamlValue;
pub(crate) use emission_plan::CompletionPass;
use emission_plan::LoweredEmissionPlan;
pub use emission_policy::{
ConditionalAnchors, EmissionClassKind, EmissionOrigin, EmissionPolicy, EmissionPolicyDelta,
EmissionSelection, InvalidEmissionPolicy, POLICY_VOCABULARY_VERSION, ResolvedEmissionPolicy,
SchemaProfile,
};
pub use emission_report::{
CanonicalizationCounts, CarrierCounts, EmissionReport, FactCounts, InsertionAbstentionCounts,
MandatoryOutcomes,
};
#[derive(Debug, Clone, PartialEq)]
pub struct PreparedValuesDocuments {
composed: YamlValue,
dependency: YamlValue,
dependency_refill: YamlValue,
}
impl PreparedValuesDocuments {
#[must_use]
pub fn new(composed: YamlValue, dependency: YamlValue, dependency_refill: YamlValue) -> Self {
Self {
composed,
dependency,
dependency_refill,
}
}
}
#[derive(Clone, Copy)]
pub struct ValuesSchemaInput<'a> {
pub contract_schema_signals: &'a ContractSchemaSignals,
pub provider: &'a dyn ResourceSchemaOracle,
pub values_documents: Option<&'a PreparedValuesDocuments>,
pub shadowed_input_paths: Option<&'a BTreeSet<String>>,
pub values_descriptions: Option<&'a BTreeMap<String, String>>,
pub emission_policy: EmissionPolicy,
}
impl<'a> ValuesSchemaInput<'a> {
pub fn new(
contract_schema_signals: &'a ContractSchemaSignals,
provider: &'a dyn ResourceSchemaOracle,
) -> Self {
Self {
contract_schema_signals,
provider,
values_documents: None,
shadowed_input_paths: None,
values_descriptions: None,
emission_policy: SchemaProfile::Full.resolved_policy().policy(),
}
}
#[must_use]
pub fn with_values_documents(mut self, values_documents: &'a PreparedValuesDocuments) -> Self {
self.values_documents = Some(values_documents);
self
}
#[must_use]
pub fn with_shadowed_input_paths(mut self, shadowed_input_paths: &'a BTreeSet<String>) -> Self {
self.shadowed_input_paths = Some(shadowed_input_paths);
self
}
#[must_use]
pub fn with_values_descriptions(
mut self,
values_descriptions: &'a BTreeMap<String, String>,
) -> Self {
self.values_descriptions = Some(values_descriptions);
self
}
#[must_use]
pub fn with_profile(mut self, profile: SchemaProfile) -> Self {
self.emission_policy = profile.resolved_policy().policy();
self
}
#[must_use]
pub fn with_emission_policy(mut self, policy: EmissionPolicy) -> Self {
self.emission_policy = policy;
self
}
}
#[tracing::instrument(skip_all)]
pub fn generate_values_schema(input: ValuesSchemaInput<'_>) -> Value {
generate_values_schema_with_report(input).0
}
#[tracing::instrument(skip_all)]
pub fn generate_values_schema_with_report(input: ValuesSchemaInput<'_>) -> (Value, EmissionReport) {
generate_values_schema_through(&input, CompletionPass::Descriptions)
}
fn generate_values_schema_through(
input: &ValuesSchemaInput<'_>,
completion_pass: CompletionPass,
) -> (Value, EmissionReport) {
let plan = LoweredEmissionPlan::build(input);
let projected = plan.project(input.emission_policy);
let completed = plan.complete(projected, completion_pass);
(completed.schema, completed.emission_report)
}
pub(crate) fn runtime_iterable_schema(allow_integer: bool) -> serde_json::Value {
let mut types = vec!["array", "object"];
if allow_integer {
types.push("integer");
}
types.push("null");
crate::schema_model::type_union_schema(types)
}
pub(crate) use helm_schema_core::split_value_path;
fn common_prefix_len(left: &[String], right: &[String]) -> usize {
left.iter()
.zip(right.iter())
.take_while(|(left, right)| left == right)
.count()
}
#[cfg(test)]
#[path = "tests/mod.rs"]
mod tests;