66
77runcpp2::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(""),
1415runcpp2::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+
2337bool 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+
145257bool 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+
377515bool 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+
401560std::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
411571std::string runcpp2::GetEscapedYAMLString (const std::string& input)
412572{
413573 std::string output = " \" " ;
0 commit comments