mirror of
https://github.com/RubyMetric/chsrc
synced 2025-07-21 07:39:35 +08:00
Strict types
This commit is contained in:
parent
286843b40b
commit
8032921182
@ -13,10 +13,10 @@
|
||||
unit module Parser;
|
||||
|
||||
#| 不能用 Bool,只能用 Boolean
|
||||
my enum ConfigItem's-ValueType <String Mode Boolean>;
|
||||
my enum ConfigItem's-ValueType < RS4C-Nil RS4C-String RS4C-Mode RS4C-Bool>;
|
||||
|
||||
#| 配置项的值
|
||||
my class ConfigItem's-Value {
|
||||
class ConfigItem's-Value {
|
||||
has ConfigItem's-ValueType $.type;
|
||||
has Str $.raw-value;
|
||||
has Any $.parsed-value;
|
||||
@ -28,17 +28,24 @@ my class ConfigItem's-Value {
|
||||
given $raw-text {
|
||||
when /^ ':' (.+) $/ {
|
||||
# 模式值 :mode
|
||||
$type = Mode;
|
||||
$type = RS4C-Mode;
|
||||
$parsed = ~$0;
|
||||
}
|
||||
when /^ ('true'|'false'|'yes'|'no') $/ {
|
||||
# 特殊字面量 - true/false/yes/no 都是 literal
|
||||
$type = Boolean;
|
||||
$type = RS4C-Bool;
|
||||
$parsed = ~$0 ~~ /^('true'|'yes')$/ ?? True !! False;
|
||||
}
|
||||
# 明确区分空字符串和无值情况
|
||||
# 这种情况不可能是用户写的(并没有nil这个字面量),只由内部实现时刻意传 Nil 出现
|
||||
when Nil {
|
||||
$type = RS4C-Nil;
|
||||
$parsed = Nil;
|
||||
}
|
||||
# 输入为空时被当做是字符串类型
|
||||
default {
|
||||
# 普通字符串
|
||||
$type = String;
|
||||
$type = RS4C-String;
|
||||
$parsed = $raw-text;
|
||||
}
|
||||
}
|
||||
@ -46,30 +53,41 @@ my class ConfigItem's-Value {
|
||||
self.bless(:$type, :raw-value($raw-text), :parsed-value($parsed));
|
||||
}
|
||||
|
||||
method as-string() {
|
||||
return $.parsed-value.Str;
|
||||
}
|
||||
|
||||
method as-bool() {
|
||||
# 获得适合调用者接受的值
|
||||
method value() {
|
||||
given $.type {
|
||||
when Boolean { return $.parsed-value; }
|
||||
when String {
|
||||
# 尝试将字符串解析为布尔值
|
||||
return $.parsed-value ~~ /^('true'|'yes')$/;
|
||||
}
|
||||
default { return False; }
|
||||
when RS4C-Nil | RS4C-String | RS4C-Bool | RS4C-Mode { return $.parsed-value; }
|
||||
default { die "Unknown config value type: {$.type}"; }
|
||||
}
|
||||
}
|
||||
|
||||
# 获取模式值(去掉冒号前缀)
|
||||
method as-mode() {
|
||||
return $.type == Mode ?? $.parsed-value !! $.raw-value;
|
||||
# 这些函数防止开发者写错类型
|
||||
method nil-value() {
|
||||
return self.value if $.type == RS4C-Nil;
|
||||
die "The config value type is not RS4C-Nil, but: {$.type}";
|
||||
}
|
||||
|
||||
method string-value() {
|
||||
return self.value if $.type == RS4C-String;
|
||||
die "The config value type is not RS4C-String, but: {$.type}";
|
||||
}
|
||||
|
||||
method bool-value() {
|
||||
return self.value if $.type == RS4C-Bool;
|
||||
die "The config value type is not RS4C-Bool, but: {$.type}";
|
||||
}
|
||||
|
||||
method mode-value() {
|
||||
return self.value if $.type == RS4C-Mode;
|
||||
die "The config value type is not RS4C-Mode, but: {$.type}";
|
||||
}
|
||||
|
||||
|
||||
# 类型检查方法
|
||||
method is-mode() { return $.type == Mode; }
|
||||
method is-bool() { return $.type == Boolean; }
|
||||
method is-string() { return $.type == String; }
|
||||
method is-nil() { return $.type == RS4C-Nil; }
|
||||
method is-mode() { return $.type == RS4C-Mode; }
|
||||
method is-bool() { return $.type == RS4C-Bool; }
|
||||
method is-string() { return $.type == RS4C-String; }
|
||||
}
|
||||
|
||||
|
||||
@ -85,8 +103,8 @@ my class ConfigBlock {
|
||||
%!items{$k} = ConfigItem's-Value.new($raw-value);
|
||||
}
|
||||
|
||||
method get($k, $default = Nil) {
|
||||
return %!items{$k} // ($default ?? ConfigItem's-Value.new($default) !! ConfigItem's-Value.new(''));
|
||||
method get($k) {
|
||||
return %!items{$k};
|
||||
}
|
||||
|
||||
method exist($k) {
|
||||
@ -102,7 +120,7 @@ my class ConfigBlock {
|
||||
|
||||
|
||||
#| 表示一个 section
|
||||
my class Section {
|
||||
class Section {
|
||||
|
||||
has Str $.title;
|
||||
has Int $.level;
|
||||
|
Loading…
x
Reference in New Issue
Block a user