///|
fn valid_condition_name(name : String) -> Bool {
let mut first = true
for c in name.iter() {
let upper = c >= 'A' && c <= 'Z'
if first {
if !upper {
return false
}
first = false
} else if !upper && !(c >= 'a' && c <= 'z') && !(c >= '0' && c <= '9') {
return false
}
}
!first
}
///|
/// Check the contract-specific rules that are not covered by schema validation.
fn Assembly::validate_conditions(
self : Assembly,
model : Model,
owner : Shape,
value : NodeValue,
) -> Unit {
if owner.body is Service(..) ||
owner.body is Operation(..) ||
owner.body is Resource(..) {
self.problem(
"SM-MODEL-011",
"I cannot apply smithy.contracts#conditions to \{owner.body.keyword()} \{owner.id}.",
owner.source,
shape=owner.id.to_string(),
)
return
}
guard value is Object(conditions) else { return }
for name, condition in conditions {
if !valid_condition_name(name) {
self.problem(
"SM-MODEL-011",
"I expected a condition name matching ^[A-Z]+[A-Za-z0-9]*$ in smithy.contracts#conditions on \{owner.id}, but found \{Json::string(name).stringify()}.",
owner.source,
shape=owner.id.to_string(),
)
}
if condition is Object(fields) &&
fields.get("expression") is Some(String(expression)) {
self.analyze_condition(model, owner, name, expression)
}
}
}