Strict types

This commit is contained in:
Aoran Zeng 2025-07-16 15:47:21 +08:00
parent 286843b40b
commit 8032921182
No known key found for this signature in database
GPG Key ID: 8F8BA8488E10ED98

View File

@ -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;