Skip to content

Commit 81bd2ab

Browse files
Adding LibYaml variant for various helper functions in ParseUtil
1 parent d6c860a commit 81bd2ab

File tree

2 files changed

+234
-2
lines changed

2 files changed

+234
-2
lines changed

Include/runcpp2/ParseUtil.hpp

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ namespace runcpp2
1414
{
1515
std::string Name;
1616
ryml::NodeType NodeType;
17+
18+
YAML::NodeType NodeType_LibYaml;
1719
bool Required;
1820
bool Nullable;
1921

@@ -22,6 +24,11 @@ namespace runcpp2
2224
ryml::NodeType nodeType,
2325
bool required,
2426
bool nullable);
27+
28+
NodeRequirement(const std::string& name,
29+
YAML::NodeType nodeType,
30+
bool required,
31+
bool nullable);
2532
};
2633

2734
bool CheckNodeRequirement( ryml::ConstNodeRef node,
@@ -33,6 +40,17 @@ namespace runcpp2
3340
bool CheckNodeRequirements( ryml::ConstNodeRef node,
3441
const std::vector<NodeRequirement>& requirements);
3542

43+
44+
bool CheckNodeRequirement_LibYaml( YAML::ConstNodePtr parentNode,
45+
const std::string childName,
46+
YAML::NodeType childType,
47+
bool required,
48+
bool nullable);
49+
50+
bool CheckNodeRequirements_LibYaml( YAML::ConstNodePtr node,
51+
const std::vector<NodeRequirement>& requirements);
52+
53+
3654
bool GetParsableInfo(const std::string& contentToParse, std::string& outParsableInfo);
3755

3856
bool ResolveYAML_Stream(ryml::Tree& rootTree,
@@ -41,10 +59,20 @@ namespace runcpp2
4159
//NOTE: Tree of both nodeToMergeTo and nodeToMergeFrom needs to be alive to be valid
4260
bool MergeYAML_NodeChildren(ryml::NodeRef nodeToMergeFrom, ryml::NodeRef nodeToMergeTo);
4361

62+
bool MergeYAML_NodeChildren_LibYaml(YAML::NodePtr nodeToMergeFrom,
63+
YAML::NodePtr nodeToMergeTo,
64+
YAML::ResourceHandle& yamlResouce);
65+
4466
bool ExistAndHasChild( ryml::ConstNodeRef node,
4567
const std::string& childName,
4668
bool nullable = false);
4769

70+
71+
bool ExistAndHasChild_LibYaml( YAML::ConstNodePtr node,
72+
const std::string& childName,
73+
bool nullable = false);
74+
75+
4876
std::string GetValue(ryml::ConstNodeRef node);
4977
std::string GetKey(ryml::ConstNodeRef node);
5078
std::string GetEscapedYAMLString(const std::string& input);
@@ -72,7 +100,7 @@ namespace runcpp2
72100
}
73101
else
74102
{
75-
if(!CheckNodeRequirement(mapNode, key, ryml::NodeType_e::MAP, false, true))
103+
if(!CheckNodeRequirement(node, key, ryml::NodeType_e::MAP, false, true))
76104
return false;
77105

78106
for(int i = 0; i < mapNode.num_children(); ++i)
@@ -92,6 +120,50 @@ namespace runcpp2
92120
}
93121
return true;
94122
}
123+
124+
125+
template<typename T>
126+
bool ParsePlatformProfileMap_LibYaml( YAML::ConstNodePtr node,
127+
const std::string& key,
128+
std::unordered_map<PlatformName, T>& result,
129+
const std::string& errorMessage)
130+
{
131+
if(ExistAndHasChild_LibYaml(node, key))
132+
{
133+
YAML::ConstNodePtr mapNode = node->GetMapValueNode(key);
134+
135+
//If we skip platform profile
136+
T defaultValue;
137+
if(defaultValue.IsYAML_NodeParsableAsDefault_LibYaml(mapNode))
138+
{
139+
if(defaultValue.ParseYAML_NodeWithProfile_LibYaml(mapNode, "DefaultProfile"))
140+
result["DefaultPlatform"] = defaultValue;
141+
else
142+
return false;
143+
}
144+
else
145+
{
146+
if(!CheckNodeRequirement_LibYaml(node, key, YAML::NodeType::Map, false, true))
147+
return false;
148+
149+
for(int i = 0; i < mapNode->GetChildrenCount(); ++i)
150+
{
151+
PlatformName platform =
152+
mapNode ->GetMapKeyScalarAt<std::string>(i)
153+
.DS_TRY_ACT(ssLOG_ERROR(DS_TMP_ERROR.ToString()); return false);
154+
T value;
155+
YAML::ConstNodePtr currentNode = mapNode->GetMapValueNodeAt(i);
156+
if(!value.ParseYAML_Node(currentNode))
157+
{
158+
ssLOG_ERROR("ScriptInfo: Failed to parse " << errorMessage);
159+
return false;
160+
}
161+
result[platform] = value;
162+
}
163+
}
164+
}
165+
return true;
166+
}
95167
}
96168

97169
#endif

Src/runcpp2/ParseUtil.cpp

Lines changed: 161 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
runcpp2::NodeRequirement::NodeRequirement() : Name(""),
88
NodeType(),
9+
NodeType_LibYaml(YAML::NodeType::Scalar),
910
Required(false),
1011
Nullable(true)
1112
{
@@ -14,12 +15,25 @@ runcpp2::NodeRequirement::NodeRequirement() : Name(""),
1415
runcpp2::NodeRequirement::NodeRequirement( const std::string& name,
1516
ryml::NodeType nodeType,
1617
bool required,
18+
bool nullable) :
19+
Name(name),
20+
NodeType(nodeType),
21+
NodeType_LibYaml(YAML::NodeType::Scalar),
22+
Required(required),
23+
Nullable(nullable)
24+
{}
25+
26+
runcpp2::NodeRequirement::NodeRequirement( const std::string& name,
27+
YAML::NodeType nodeType,
28+
bool required,
1729
bool nullable) : Name(name),
18-
NodeType(nodeType),
30+
NodeType(),
31+
NodeType_LibYaml(nodeType),
1932
Required(required),
2033
Nullable(nullable)
2134
{}
2235

36+
2337
bool runcpp2::CheckNodeRequirement( ryml::ConstNodeRef node,
2438
const std::string name,
2539
ryml::NodeType nodeType,
@@ -142,6 +156,104 @@ bool runcpp2::CheckNodeRequirements(ryml::ConstNodeRef node,
142156
INTERNAL_RUNCPP2_SAFE_CATCH_RETURN(false);
143157
}
144158

159+
bool runcpp2::CheckNodeRequirement_LibYaml( YAML::ConstNodePtr parentNode,
160+
const std::string childName,
161+
YAML::NodeType childType,
162+
bool required,
163+
bool nullable)
164+
{
165+
ssLOG_FUNC_DEBUG();
166+
167+
if(!parentNode->IsMap())
168+
{
169+
ssLOG_ERROR("Node is not a map: " << parentNode->Value.index());
170+
return false;
171+
}
172+
173+
ssLOG_DEBUG("Checking: " << childName << " exists");
174+
if(!ExistAndHasChild_LibYaml(parentNode, childName, nullable))
175+
{
176+
if(required)
177+
{
178+
if(false)
179+
{
180+
ssLOG_DEBUG("node.num_children(): " << parentNode->GetChildrenCount());
181+
for(int j = 0; j < parentNode->GetChildrenCount(); ++j)
182+
ssLOG_DEBUG(parentNode->GetMapKeyScalarAt<std::string>(j).value_or(""));
183+
}
184+
185+
ssLOG_ERROR("Required field not found: " << childName);
186+
return false;
187+
}
188+
return true;
189+
}
190+
191+
//If type is nullable, we cannot verify it's type, so just continue
192+
YAML::ConstNodePtr childNode = parentNode->GetMapValueNode(childName);
193+
if(nullable && childNode->IsScalar() && childNode->GetScalar<StringView>().value_or("").empty())
194+
return true;
195+
196+
if(childNode->GetType() != childType)
197+
{
198+
ssLOG_ERROR("Field type is invalid: " << childName);
199+
ssLOG_ERROR("Expected: " << YAML::NodeTypeToString(childType));
200+
ssLOG_ERROR("Found: " << YAML::NodeTypeToString(childNode->GetType()));
201+
return false;
202+
}
203+
204+
return true;
205+
}
206+
207+
bool runcpp2::CheckNodeRequirements_LibYaml(YAML::ConstNodePtr node,
208+
const std::vector<NodeRequirement>& requirements)
209+
{
210+
ssLOG_FUNC_DEBUG();
211+
212+
if(!node->IsMap())
213+
{
214+
ssLOG_ERROR("Node is not a map: " << YAML::NodeTypeToString(node->GetType()));
215+
ssLOG_ERROR("Node is not a map");
216+
return false;
217+
}
218+
219+
//All keys must be unique
220+
{
221+
std::unordered_set<std::string> childKeys;
222+
for(int i = 0; i < node->GetChildrenCount(); ++i)
223+
{
224+
YAML::ConstNodePtr keyNode = node->GetMapKeyNodeAt(i);
225+
if(!keyNode->IsScalar())
226+
{
227+
ssLOG_ERROR("Key must be scalar");
228+
return false;
229+
}
230+
231+
std::string currentKey = (std::string)keyNode->GetScalar<StringView>().value_or("");
232+
if(childKeys.count(currentKey) != 0)
233+
{
234+
ssLOG_ERROR("Duplicate key found for: " << currentKey);
235+
return false;
236+
}
237+
else
238+
childKeys.insert(currentKey);
239+
}
240+
}
241+
242+
for(int i = 0; i < requirements.size(); ++i)
243+
{
244+
if(!CheckNodeRequirement_LibYaml( node,
245+
requirements[i].Name,
246+
requirements[i].NodeType_LibYaml,
247+
requirements[i].Required,
248+
requirements[i].Nullable))
249+
{
250+
return false;
251+
}
252+
}
253+
254+
return true;
255+
}
256+
145257
bool runcpp2::GetParsableInfo(const std::string& contentToParse, std::string& outParsableInfo)
146258
{
147259
ssLOG_FUNC_DEBUG();
@@ -374,6 +486,32 @@ bool runcpp2::MergeYAML_NodeChildren(ryml::NodeRef nodeToMergeFrom, ryml::NodeRe
374486
INTERNAL_RUNCPP2_SAFE_CATCH_RETURN(false);
375487
}
376488

489+
bool runcpp2::MergeYAML_NodeChildren_LibYaml( YAML::NodePtr nodeToMergeFrom,
490+
YAML::NodePtr nodeToMergeTo,
491+
YAML::ResourceHandle& yamlResouce)
492+
{
493+
ssLOG_FUNC_DEBUG();
494+
495+
if(!nodeToMergeFrom->IsMap() || !nodeToMergeTo->IsMap())
496+
{
497+
ssLOG_ERROR("Merge node is not map");
498+
return false;
499+
}
500+
501+
for(int i = 0; i < nodeToMergeFrom->GetChildrenCount(); ++i)
502+
{
503+
std::string key = nodeToMergeFrom->GetMapKeyScalarAt<std::string>(i).DS_TRY_ACT(return false);
504+
505+
if(!ExistAndHasChild_LibYaml(nodeToMergeTo, key, true))
506+
{
507+
YAML::NodePtr fromNode = nodeToMergeFrom->GetMapValueNodeAt(i);
508+
fromNode->CloneToMapChild(key, nodeToMergeTo, yamlResouce).DS_TRY_ACT(return false);
509+
}
510+
}
511+
512+
return true;
513+
}
514+
377515
bool runcpp2::ExistAndHasChild( ryml::ConstNodeRef node,
378516
const std::string& childName,
379517
bool nullable)
@@ -398,6 +536,27 @@ bool runcpp2::ExistAndHasChild( ryml::ConstNodeRef node,
398536
INTERNAL_RUNCPP2_SAFE_CATCH_RETURN(false);
399537
}
400538

539+
bool runcpp2::ExistAndHasChild_LibYaml( runcpp2::YAML::ConstNodePtr node,
540+
const std::string& childName,
541+
bool nullable)
542+
{
543+
ssLOG_FUNC_DEBUG();
544+
545+
if(node->GetChildrenCount() > 0 && node->IsMap() && node->HasMapKey(childName))
546+
{
547+
YAML::ConstNodePtr mapVal = node->GetMapValueNode(childName);
548+
if(!mapVal)
549+
return false;
550+
551+
if(!nullable && mapVal->IsScalar() && mapVal->GetScalar<StringView>().value_or("").empty())
552+
return false;
553+
554+
return true;
555+
}
556+
557+
return false;
558+
}
559+
401560
std::string runcpp2::GetValue(ryml::ConstNodeRef node)
402561
{
403562
return std::string(node.val().str, node.val().len);
@@ -408,6 +567,7 @@ std::string runcpp2::GetKey(ryml::ConstNodeRef node)
408567
return std::string(node.key().str, node.key().len);
409568
}
410569

570+
//TODO: Replace with string escape in libyaml wrapper
411571
std::string runcpp2::GetEscapedYAMLString(const std::string& input)
412572
{
413573
std::string output = "\"";

0 commit comments

Comments
 (0)