///|
/// Require a string to start with `prefix`.
pub fn Typed::starts_with(
self : Typed[String],
prefix : String,
) -> Typed[String] raise Invalid {
if self.val.has_prefix(prefix) {
self
} else {
err(self.path, "must start with \{prefix}")
}
}
///|
/// Require a string to end with `suffix`.
pub fn Typed::ends_with(
self : Typed[String],
suffix : String,
) -> Typed[String] raise Invalid {
if self.val.has_suffix(suffix) {
self
} else {
err(self.path, "must end with \{suffix}")
}
}
///|
/// Require a string to contain `part`.
pub fn Typed::includes(
self : Typed[String],
part : String,
) -> Typed[String] raise Invalid {
if self.val.contains(part) {
self
} else {
err(self.path, "must include \{part}")
}
}
///|
/// Require a string to be lowercase.
pub fn Typed::lowercase(self : Typed[String]) -> Typed[String] raise Invalid {
if is_lowercase(self.val) {
self
} else {
err(self.path, "must be lowercase")
}
}
///|
/// Require a string to be uppercase.
pub fn Typed::uppercase(self : Typed[String]) -> Typed[String] raise Invalid {
if is_uppercase(self.val) {
self
} else {
err(self.path, "must be uppercase")
}
}
///|
/// Require a string to contain a MoonBit regex match.
/// Use `^` and `$` to require the whole string.
pub fn Typed::regex(
self : Typed[String],
pattern : String,
) -> Typed[String] raise Invalid {
if regex_matches(pattern, self.val) {
self
} else {
err(self.path, "must match pattern")
}
}
///|
fn is_lowercase(s : StringView) -> Bool {
s.to_lower().to_owned() == s.to_owned()
}
///|
fn is_uppercase(s : StringView) -> Bool {
s.to_upper().to_owned() == s.to_owned()
}
///|
fn regex_matches(pattern : StringView, s : StringView) -> Bool {
let re = @string.Regex::unsafe_from_string(pattern)
re.execute(s) is Some(_)
}