在 CueLang 中将结构的两个字段声明为互斥?



我想确保我的用户只设置以下两个字段之一:

rotations:
- type: weekly
time_restrictions:
# Allow only ONE of the following fields:
weekday_time_of_day: {...}
time_of_day: [...]       

我在 Cuetorials 上遇到了OneOf模式,但这似乎仅在想要在编写提示文件时强制执行架构时才有帮助。


#OneOfTimeRestrictions: {time_of_day: [...string]} | {weekday_time_of_day: [...string]}
rotations: [{
type:         *"weekly" | "daily"
restrictions: #OneOfTimeRestrictions | {} // won't work, naturally, because nothing is "chosen" 
}]

(互斥字段的值实际上是额外的、更复杂的结构,而不是字符串,以防万一 - 但为了一个更简短的例子,我省略了它们。

但是,我正在尝试审查 YAML

问题是,在定义它时:

#OneOfTimeRestrictions: rotations: [{
type:         *"weekly" | "daily"
restrictions: {time_of_day: [...string]} | {weekday_time_of_day: [...string]}
}]

这两个字段都是可以接受的,包括同时提供它们时。

指针?

不是提示专家,但
in CUE{}可以是封闭结构,也可以是开放结构,具体取决于上下文.
#A: {}是一个封闭架构,这意味着您无法向其添加新字段.
虽然B:{}是一个开放值,您可以在其中添加新字段。

#A:{}
a: a & {someKey: true} // will produce an error
B:{}
b: b & {someKey: true} // will pass
_C:{}
c: _C & {someKey: true} // will pass

(你可以在这里测试它:https://cuelang.org/play/?id=XigxaAJ1bcp#cue@export@cue)
(并在此处阅读更多相关信息:https://cuetorials.com/deep-dives/closedness/)

因此,在您的第一个 CUE 代码示例中,第restrictions: #OneOfTimeRestrictions | {}行表示restrictions必须将封闭架构与weekday_time_of_daytime_of_day字段匹配,而没有其他任何内容,或者必须匹配将匹配每个非空对象的未闭合{}

在第二个代码示例中,您说restictions匹配具有weekday_time_of_day字段的开放结构或匹配具有time_of_day字段的开放结构。所以,它们基本上是相同的。

像这样尝试

#OneOfTimeRestrictions: {time_of_day: [...string]} | {weekday_time_of_day: [...string]}

#Restrictions: {
restrictionA: string
restrictionB: bool
// ...
restrictionZ: bool
#OneOfTimeRestrictions
}
rotations: [...{
type: *"weekly" | "daily"
restrictions: #Restrictions
}]

或者,如果您不喜欢其他架构,如下所示

#OneOfTimeRestrictions: {time_of_day: [...string]} | {weekday_time_of_day: [...string]}
rotations: [...{
type: *"weekly" | "daily"
restrictions: {
restrictionA:     string
restrictionB:     bool
// ...
restrictionZ: bool

#OneOfTimeRestrictions
}
}]

但是这些解决方案将使relations的对象关闭。因此,您将故意定义每个附加限制.
(我不确定为什么restrictions在我的第二个示例中很接近,但在我的测试中它是关闭的)。

如果您需要打开relations中的对象,可以使用如下内容:

rotations: [...{
type: *"weekly" | "daily"
restrictions: {
time_of_day: [...string]
weekday_time_of_day: [...string]
_tr1: bool | *false
_tr2: bool | *false
if time_of_day == [] {
_tr1: true
}
if weekday_time_of_day == [] {
_tr2: true
}
_time_restiction_valid: true
_time_restiction_valid: (_tr1 && !_tr2) || (!_tr1 && _tr2) // append '|| (!_tr1 && !_tr2)' if you want to allow that nither can be set
}
}]

最新更新