void cfg::encode(YAML::Emitter& out, const cfg::_base& rhs) { switch (rhs.get_type()) { case type::node: { out << YAML::BeginMap; for (const auto& np : static_cast<const node&>(rhs).get_nodes()) { out << YAML::Key << np.first; out << YAML::Value; encode(out, *np.second); } out << YAML::EndMap; return; } case type::set: { out << YAML::BeginSeq; for (const auto& str : static_cast<const set_entry&>(rhs).get_set()) { out << str; } out << YAML::EndSeq; return; } case type::log: { out << YAML::BeginMap; for (const auto& np : static_cast<const log_entry&>(rhs).get_map()) { if (np.second == logs::level::notice) continue; out << YAML::Key << np.first; out << YAML::Value << fmt::format("%s", np.second); } out << YAML::EndMap; return; } default: { out << rhs.to_string(); return; } } }
void cfg::decode(const YAML::Node& data, cfg::_base& rhs) { switch (rhs.get_type()) { case type::node: { if (data.IsScalar() || data.IsSequence()) { return; // ??? } for (const auto& pair : data) { if (!pair.first.IsScalar()) continue; // Find the key among existing nodes for (const auto& _pair : static_cast<node&>(rhs).get_nodes()) { if (_pair.first == pair.first.Scalar()) { decode(pair.second, *_pair.second); } } } break; } case type::set: { std::vector<std::string> values; if (YAML::convert<decltype(values)>::decode(data, values)) { rhs.from_list(std::move(values)); } break; } case type::log: { if (data.IsScalar() || data.IsSequence()) { return; // ??? } std::map<std::string, logs::level> values; for (const auto& pair : data) { if (!pair.first.IsScalar() || !pair.second.IsScalar()) continue; u64 value; if (cfg::try_to_enum_value(&value, &fmt_class_string<logs::level>::format, pair.second.Scalar())) { values.emplace(pair.first.Scalar(), static_cast<logs::level>(static_cast<int>(value))); } } static_cast<log_entry&>(rhs).set_map(std::move(values)); break; } default: { std::string value; if (YAML::convert<std::string>::decode(data, value)) { rhs.from_string(value); } break; // ??? } } }