///|
pub struct ValidationPolicy {
require_file : Bool
require_sources_content : Bool
forbid_empty_sources : Bool
forbid_empty_names : Bool
allow_unmapped_segments : Bool
allow_ignore_list : Bool
max_segment_count : Int?
max_source_count : Int?
} derive(Eq, Debug, ToJson)
///|
pub fn ValidationPolicy::ValidationPolicy(
require_file? : Bool = false,
require_sources_content? : Bool = false,
forbid_empty_sources? : Bool = true,
forbid_empty_names? : Bool = false,
allow_unmapped_segments? : Bool = true,
allow_ignore_list? : Bool = true,
max_segment_count? : Int,
max_source_count? : Int,
) -> ValidationPolicy {
{
require_file,
require_sources_content,
forbid_empty_sources,
forbid_empty_names,
allow_unmapped_segments,
allow_ignore_list,
max_segment_count,
max_source_count,
}
}
///|
pub fn ValidationPolicy::default() -> ValidationPolicy {
{
require_file: false,
require_sources_content: false,
forbid_empty_sources: true,
forbid_empty_names: false,
allow_unmapped_segments: true,
allow_ignore_list: true,
max_segment_count: None,
max_source_count: None,
}
}
///|
pub fn ValidationPolicy::strict() -> ValidationPolicy {
{
require_file: true,
require_sources_content: true,
forbid_empty_sources: true,
forbid_empty_names: true,
allow_unmapped_segments: false,
allow_ignore_list: true,
max_segment_count: None,
max_source_count: None,
}
}
///|
pub fn ValidationPolicy::with_unmapped_segments(
self : ValidationPolicy,
allow : Bool,
) -> ValidationPolicy {
{ ..self, allow_unmapped_segments: allow }
}
///|
pub fn ValidationPolicy::with_ignore_list(
self : ValidationPolicy,
allow : Bool,
) -> ValidationPolicy {
{ ..self, allow_ignore_list: allow }
}
///|
pub fn ValidationPolicy::with_limits(
self : ValidationPolicy,
max_segment_count? : Int,
max_source_count? : Int,
) -> ValidationPolicy {
{ ..self, max_segment_count, max_source_count }
}
///|
pub fn SourceMap::validate_with(
self : SourceMap,
policy : ValidationPolicy,
) -> Array[Diagnostic] {
let diagnostics = self.validate()
if policy.require_file && self.file is None {
diagnostics.push(
diag_error("policy.file", "file", "policy requires file field"),
)
}
if policy.require_sources_content {
if self.sources_content.length() != self.sources.length() {
diagnostics.push(
diag_error(
"policy.sourcesContent", "sourcesContent", "policy requires sourcesContent for every source",
),
)
} else {
for i, content in self.sources_content {
if content is None {
diagnostics.push(
diag_error(
"policy.sourcesContent.item",
"sourcesContent[\{i}]",
"policy requires inline source content",
),
)
}
}
}
}
if policy.forbid_empty_sources {
for i, source in self.sources {
if source.length() == 0 {
diagnostics.push(
diag_error(
"policy.source.empty",
"sources[\{i}]",
"empty source is forbidden",
),
)
}
}
}
if policy.forbid_empty_names {
for i, name in self.names {
if name.length() == 0 {
diagnostics.push(
diag_error(
"policy.name.empty",
"names[\{i}]",
"empty name is forbidden",
),
)
}
}
}
if !policy.allow_unmapped_segments {
for i, segment in self.mappings {
if !segment.is_mapped() {
diagnostics.push(
diag_error(
"policy.unmapped",
"mappings[\{i}]",
"unmapped segment is forbidden by policy",
),
)
}
}
}
if !policy.allow_ignore_list && self.ignore_list.length() > 0 {
diagnostics.push(
diag_error(
"policy.ignoreList", "ignoreList", "ignoreList is forbidden by policy",
),
)
}
if policy.max_segment_count is Some(limit) {
if self.mappings.length() > limit {
diagnostics.push(
diag_error(
"policy.maxSegments",
"mappings",
"segment count \{self.mappings.length()} exceeds limit \{limit}",
),
)
}
}
if policy.max_source_count is Some(limit) {
if self.sources.length() > limit {
diagnostics.push(
diag_error(
"policy.maxSources",
"sources",
"source count \{self.sources.length()} exceeds limit \{limit}",
),
)
}
}
diagnostics
}
///|
pub fn SourceMap::passes_policy(
self : SourceMap,
policy : ValidationPolicy,
) -> Bool {
!self.validate_with(policy).any(diagnostic => diagnostic.severity == "error")
}