载入中...
搜索中...
未找到
ConditionWatch.cpp
浏览该文件的文档.
2
4
5#include "common/Diagnostic.h"
6
7#include <algorithm>
8#include <set>
9
10namespace eve::emergence {
11namespace {
12
13void insertUnique(std::set<std::string>& out, std::string key) {
14 if (!key.empty()) out.insert(std::move(key));
15}
16
17eve::Result<void> walk(const decision::Condition& condition, std::set<std::string>& out) {
19 switch (condition.kind()) {
20 case K::All:
21 case K::Any:
22 for (const auto& child : condition.children()) {
23 auto nested = walk(child, out);
24 if (!nested) return nested;
25 }
27 case K::Not:
28 if (condition.children().empty())
30 "not condition requires a child", "children",
31 {}, "emergence.watch"));
32 return walk(condition.children().front(), out);
33 case K::Compare:
34 insertUnique(out, makeFactKey(FactDomain::Value, condition.key()));
36 case K::HasTag:
37 insertUnique(out, makeFactKey(FactDomain::Tag, condition.key()));
39 case K::HasAttribute:
40 insertUnique(out, makeFactKey(FactDomain::Attribute, condition.key()));
42 case K::HasResource:
43 insertUnique(out, makeFactKey(FactDomain::Resource, condition.key()));
45 case K::StateEquals:
46 insertUnique(out, makeFactKey(FactDomain::State, condition.key()));
48 case K::AuthorityCheck:
49 insertUnique(out, makeFactKey(FactDomain::Authority, condition.key()));
51 case K::PolicyCall: {
52 insertUnique(out, makeFactKey(FactDomain::Policy, condition.key()));
53 const auto& declaration = condition.scriptDeclaration();
54 if (declaration) {
55 for (const auto& dependency : declaration->dependencies) {
56 auto parsed = parseFactKey(dependency);
57 if (!parsed)
60 "policy_call dependency must use canonical domain:name fact key form", "dependencies", {},
61 "emergence.watch"));
62 insertUnique(out, dependency);
63 }
64 }
65 if (out.empty() || (declaration && declaration->dependencies.empty() && condition.key().empty())) {
68 "policy_call conditions require a policy name or declared dependencies for indexing", "policy", {},
69 "emergence.watch"));
70 }
72 }
73 }
75 "unknown condition kind while collecting watch keys",
76 "kind", {}, "emergence.watch"));
77}
78
79} // namespace
80
82 if (!condition.isValid())
84 eve::DiagnosticCode::InvalidArgument, "condition tree is invalid", "condition", {}, "emergence.watch"));
85 std::set<std::string> unique;
86 auto walked = walk(condition, unique);
87 if (!walked) return eve::Result<std::vector<std::string>>::failure(walked.status());
88 if (unique.empty())
91 "condition produced no watch keys; empty All nodes cannot be indexed alone",
92 "condition", {}, "emergence.watch"));
93 return eve::Result<std::vector<std::string>>::success(std::vector<std::string>(unique.begin(), unique.end()));
94}
95
96} // namespace eve::emergence
Derive inverted-index watch keys from a decision::Condition AST.
Stable, structured diagnostics shared by engine modules.
eve::Value condition
Authoritative, rule-visible world facts implementing EvaluationContext.
std::uint32_t key
int children
Definition TreeMesh.cpp:295
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
Type kind() const noexcept
Compatibility spelling for the former dialogue data tree.
Definition Value.h:85
Immutable condition AST node.
Definition Condition.h:195
ConditionKind
Node kind in the side-effect-free condition AST.
Definition Condition.h:22
eve::Result< std::vector< std::string > > collectWatchKeys(const decision::Condition &condition)
Collect the canonical fact keys a condition depends on.
eve::Result< std::pair< FactDomain, std::string > > parseFactKey(std::string_view key)
Parse a canonical watch key into domain and leaf name.
std::string makeFactKey(FactDomain domain, std::string_view name)
Build the canonical watch key for one fact domain.