///|
/// A command the CLI, the web UI and the desktop shell all understand.
pub(all) enum Command {
Help
Version
} derive(Eq, Debug)
///|
/// Raised when a text names no command.
pub(all) suberror CommandError {
/// The text is not the name or an alias of a command.
UnknownCommand(String)
} derive(Eq, Debug)
///|
/// Every command, in the order that the help text lists them.
pub let commands : ReadOnlyArray[Command] = [Help, Version]
///|
/// Reads a command name. `--help`, `-h`, `--version` and `-V` are accepted.
pub fn Command::Command(name : String) -> Command raise CommandError {
match name {
"help" | "--help" | "-h" => Help
"version" | "--version" | "-V" => Version
_ => raise UnknownCommand(name)
}
}
///|
/// The name of the command on the command line.
pub fn Command::name(self : Command) -> String {
match self {
Help => "help"
Version => "version"
}
}
///|
/// The ID of the Proton command that the desktop shell exposes.
pub fn Command::proton_id(self : Command) -> String {
"mission-control." + self.name()
}
///|
/// One line that describes the command in the help text.
pub fn Command::description(self : Command) -> String {
match self {
Help => "Print this help"
Version => "Print the version"
}
}
///|
/// Raised when a text is not a version.
pub(all) suberror VersionError {
/// The text is not three non-negative integers joined with `.`, without
/// leading zeros.
InvalidVersion(String)
} derive(Eq, Debug)
///|
/// A version such as `0.0.2`: three non-negative integer parts.
struct Version {
major : Int32
minor : Int32
patch : Int32
} derive(Eq, Compare, Hash, Debug)
///|
/// Parses `X.Y.Z`. Each part is a non-negative integer with at most nine
/// digits and no leading zero.
pub fn Version::Version(text : String) -> Version raise VersionError {
let parts = text.split(".").map(p => p.to_owned()).collect()
guard parts.length() == 3 else { raise InvalidVersion(text) }
let numbers = []
for part in parts {
let ok = part.length() > 0 &&
part.length() <= 9 &&
part.iter().all(c => c >= '0' && c <= '9') &&
!(part.length() > 1 && part.has_prefix("0"))
guard ok else { raise InvalidVersion(text) }
let mut n = 0
for c in part {
n = n * 10 + (c.to_int() - '0'.to_int())
}
numbers.push(n)
}
{ major: numbers[0], minor: numbers[1], patch: numbers[2], }
}
///|
pub fn Version::major(self : Version) -> Int32 {
self.major
}
///|
pub fn Version::minor(self : Version) -> Int32 {
self.minor
}
///|
pub fn Version::patch(self : Version) -> Int32 {
self.patch
}
///|
pub fn Version::to_string(self : Version) -> String {
"\{self.major}.\{self.minor}.\{self.patch}"
}
///|
pub impl Show for Version with fn output(self, logger) {
logger.write_string(self.to_string())
}
///|
/// The version text of this module. `scripts/versions.mbtx` sets it to the
/// workspace version.
let current_version : String = "0.1.0"
///|
/// The version of this module. It matches the workspace version.
pub fn Version::current() -> Version {
// A test checks that the text above parses.
Version::Version(current_version) catch {
_ => abort("the contract version is not a version: \{current_version}")
}
}
///|
/// The version of this module. It matches the workspace version.
pub fn version() -> Version {
Version::current()
}
///|
pub extend Command with Eq::{not_equal, equal}
///|
pub extend Command with @debug.Debug::{to_repr}
///|
pub extend CommandError with Eq::{not_equal, equal}
///|
pub extend CommandError with @debug.Debug::{to_repr}
///|
pub extend VersionError with Eq::{not_equal, equal}
///|
pub extend VersionError with @debug.Debug::{to_repr}
///|
pub extend Version with Eq::{not_equal, equal}
///|
pub extend Version with Compare::{op_lt, op_le, op_ge, compare, op_gt}
///|
pub extend Version with Hash::{hash, hash_combine}
///|
pub extend Version with @debug.Debug::{to_repr}
///|
pub extend Version with Show::{output}