
Ordering.pudu
Pudu96 lines5.0 KB
1/** @Validation.Rules.Ordering.Module — checks ordered property bounds */2module PuduLangValidator.Rules.Ordering34import Std.Order {Ord}5import PuduLangValidator.Rule as Rule678export fn greaterThan[T, V: Ord](builder: Rule.RuleBuilder[T, V], bound: V) -> Rule.RuleBuilder[T, V] {9 Rule.withArgument(Rule.withCode(Rule.withMessage(Rule.must(builder, |value: V| bound.before(&value)),10 "Value must be greater than \{ComparisonValue\}."), "GreaterThan"), "ComparisonValue", bound.toText())11}121314export fn greaterThanOrEqualTo[T, V: Ord](builder: Rule.RuleBuilder[T, V], bound: V) -> Rule.RuleBuilder[T, V] {15 Rule.withArgument(Rule.withCode(Rule.withMessage(Rule.must(builder, |value: V| !value.before(&bound)),16 "Value must be at least \{ComparisonValue\}."), "GreaterThanOrEqualTo"), "ComparisonValue", bound.toText())17}181920export fn lessThan[T, V: Ord](builder: Rule.RuleBuilder[T, V], bound: V) -> Rule.RuleBuilder[T, V] {21 Rule.withArgument(Rule.withCode(Rule.withMessage(Rule.must(builder, |value: V| value.before(&bound)),22 "Value must be less than \{ComparisonValue\}."), "LessThan"), "ComparisonValue", bound.toText())23}242526export fn lessThanOrEqualTo[T, V: Ord](builder: Rule.RuleBuilder[T, V], bound: V) -> Rule.RuleBuilder[T, V] {27 Rule.withArgument(Rule.withCode(Rule.withMessage(Rule.must(builder, |value: V| !bound.before(&value)),28 "Value must be at most \{ComparisonValue\}."), "LessThanOrEqualTo"), "ComparisonValue", bound.toText())29}303132export fn greaterThanProperty[T, V: Ord](33 builder: Rule.RuleBuilder[T, V], path: Str, select: fn(T) -> V34) -> Rule.RuleBuilder[T, V] {35 let checked = Rule.withCode(Rule.withMessage(Rule.mustWithArguments(builder,36 fn(root: T, value: V) -> Option[Array[(Str, Str)]] {37 let bound = select(root)38 if bound.before(&value) { None } else { Some([("ComparisonValue", bound.toText())]) }39 }),40 "Value must be greater than \{ComparisonValue\} from \{ComparisonProperty\}."), "GreaterThan")41 Rule.withArgument(checked, "ComparisonProperty", path)42}434445export fn greaterThanOrEqualToProperty[T, V: Ord](46 builder: Rule.RuleBuilder[T, V], path: Str, select: fn(T) -> V47) -> Rule.RuleBuilder[T, V] {48 let checked = Rule.withCode(Rule.withMessage(Rule.mustWithArguments(builder,49 fn(root: T, value: V) -> Option[Array[(Str, Str)]] {50 let bound = select(root)51 if !value.before(&bound) { None } else { Some([("ComparisonValue", bound.toText())]) }52 }),53 "Value must be at least \{ComparisonValue\} from \{ComparisonProperty\}."), "GreaterThanOrEqualTo")54 Rule.withArgument(checked, "ComparisonProperty", path)55}565758export fn lessThanProperty[T, V: Ord](59 builder: Rule.RuleBuilder[T, V], path: Str, select: fn(T) -> V60) -> Rule.RuleBuilder[T, V] {61 let checked = Rule.withCode(Rule.withMessage(Rule.mustWithArguments(builder,62 fn(root: T, value: V) -> Option[Array[(Str, Str)]] {63 let bound = select(root)64 if value.before(&bound) { None } else { Some([("ComparisonValue", bound.toText())]) }65 }),66 "Value must be less than \{ComparisonValue\} from \{ComparisonProperty\}."), "LessThan")67 Rule.withArgument(checked, "ComparisonProperty", path)68}697071export fn lessThanOrEqualToProperty[T, V: Ord](72 builder: Rule.RuleBuilder[T, V], path: Str, select: fn(T) -> V73) -> Rule.RuleBuilder[T, V] {74 let checked = Rule.withCode(Rule.withMessage(Rule.mustWithArguments(builder,75 fn(root: T, value: V) -> Option[Array[(Str, Str)]] {76 let bound = select(root)77 if !bound.before(&value) { None } else { Some([("ComparisonValue", bound.toText())]) }78 }),79 "Value must be at most \{ComparisonValue\} from \{ComparisonProperty\}."), "LessThanOrEqualTo")80 Rule.withArgument(checked, "ComparisonProperty", path)81}828384export fn inclusiveBetween[T, V: Ord](builder: Rule.RuleBuilder[T, V], low: V, high: V) -> Rule.RuleBuilder[T, V] {85 let checked = Rule.withCode(Rule.withMessage(Rule.must(builder, |value: V| !value.before(&low) && !high.before(&value)),86 "Value must be from \{From\} through \{To\}."), "InclusiveBetween")87 Rule.withArgument(Rule.withArgument(checked, "From", low.toText()), "To", high.toText())88}899091export fn exclusiveBetween[T, V: Ord](builder: Rule.RuleBuilder[T, V], low: V, high: V) -> Rule.RuleBuilder[T, V] {92 let checked = Rule.withCode(Rule.withMessage(Rule.must(builder, |value: V| low.before(&value) && value.before(&high)),93 "Value must be strictly between \{From\} and \{To\}."), "ExclusiveBetween")94 Rule.withArgument(Rule.withArgument(checked, "From", low.toText()), "To", high.toText())95}96