| 68 | } // namespace detail |
| 69 | |
| 70 | void |
| 71 | SetRecordFromYAMLNode(CfgNode const &field, swoc::Errata &errata) |
| 72 | { |
| 73 | std::string record_name{field.get_record_name()}; |
| 74 | RecT rec_type{RecT::RECT_CONFIG}; |
| 75 | RecDataT data_type{RecDataT::RECD_NULL}; |
| 76 | RecCheckT check_type{RecCheckT::RECC_NULL}; |
| 77 | std::string check_expr; |
| 78 | // this function (GetRec..) should be generic and possibly getting the value either |
| 79 | // from where it gets it currently or a schema file. |
| 80 | if (const auto *found = GetRecordElementByName(record_name.c_str()); found) { |
| 81 | if (REC_TYPE_IS_STAT(found->type)) { |
| 82 | ink_release_assert(REC_TYPE_IS_STAT(found->type)); |
| 83 | } |
| 84 | rec_type = found->type; |
| 85 | data_type = found->value_type; |
| 86 | check_type = found->check; |
| 87 | if (found->regex) { |
| 88 | check_expr = found->regex; |
| 89 | } |
| 90 | } else { |
| 91 | // Not registered in ATS, could be a plugin or an invalid(not registered) records. |
| 92 | // Externally registered records should have the type set in each field (!!int, !!float, etc), otherwise we will not be able to |
| 93 | // deduce the type and we could end up doing a bad type cast at the end. So we say if there is no type(tag) specified, then |
| 94 | // we ignore it. |
| 95 | auto [dtype, e] = detail::try_deduce_type(field.value_node); |
| 96 | if (!e.empty()) { |
| 97 | errata.note(ERRATA_WARN, "Ignoring field '{}' [{}] at {}. Not registered and {}", field.node.as<std::string>(), |
| 98 | field.get_record_name(), field.mark_as_view("line={}, col={}"), e); |
| 99 | // We can't continue without knowing the type. |
| 100 | return; |
| 101 | } |
| 102 | data_type = dtype; // field tags found. |
| 103 | } |
| 104 | |
| 105 | // It could happen that a field was set to null. We only care for string type, we want |
| 106 | // this to be explicitly set so the librecords can deal with this. For non strings we |
| 107 | // will use the default value. |
| 108 | // |
| 109 | if (YAML::NodeType::Null == field.value_node.Type()) { |
| 110 | switch (data_type) { |
| 111 | case RecDataT::RECD_INT: |
| 112 | case RecDataT::RECD_FLOAT: |
| 113 | errata.note(ERRATA_DEBUG, "Field '{}' set to null. Default value will be used", field.node.as<std::string>()); |
| 114 | return; |
| 115 | default:; |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | std::string field_value = field.value_node.as<std::string>(); // in case of a string, the library will give us the literal |
| 120 | // 'null' which is exactly what we want. |
| 121 | |
| 122 | std::string value_str = RecConfigOverrideFromEnvironment(record_name.c_str(), field_value.c_str()); |
| 123 | RecSourceT source = (field_value == value_str ? REC_SOURCE_EXPLICIT : REC_SOURCE_ENV); |
| 124 | |
| 125 | if (source == REC_SOURCE_ENV) { |
| 126 | errata.note(ERRATA_DEBUG, "'{}' was override with '{}' using an env variable", record_name, value_str); |
| 127 | } |
nothing calls this directly
no test coverage detected