118 lines
2.7 KiB
C++
118 lines
2.7 KiB
C++
#pragma once
|
|
#include <string>
|
|
#include <vector>
|
|
#include <unordered_map>
|
|
#include <sstream>
|
|
#include <algorithm>
|
|
#include <cctype>
|
|
|
|
namespace yamal_ns {
|
|
|
|
template<typename Value>
|
|
class ordered_map {
|
|
std::unordered_map<std::string, Value> map;
|
|
std::vector<std::string> keys;
|
|
|
|
public:
|
|
Value& operator[](const std::string& key) {
|
|
if (!map.contains(key)) keys.push_back(key);
|
|
return map[key];
|
|
}
|
|
|
|
bool contains(const std::string& key) const {
|
|
return map.find(key) != map.end();
|
|
}
|
|
|
|
void erase(const std::string& key) {
|
|
if (map.erase(key)) {
|
|
keys.erase(std::remove(keys.begin(), keys.end(), key), keys.end());
|
|
}
|
|
}
|
|
|
|
void clear() {
|
|
map.clear();
|
|
keys.clear();
|
|
}
|
|
|
|
size_t size() const { return keys.size(); }
|
|
|
|
std::vector<std::pair<std::string, Value>> items() const {
|
|
std::vector<std::pair<std::string, Value>> result;
|
|
for (const auto& k : keys) result.emplace_back(k, map.at(k));
|
|
return result;
|
|
}
|
|
|
|
const Value& at(const std::string& key) const { return map.at(key); }
|
|
Value& at(const std::string& key) { return map.at(key); }
|
|
};
|
|
|
|
class yamal {
|
|
public:
|
|
enum Mode { SCALAR, VECTOR, MAP };
|
|
Mode mode = SCALAR;
|
|
|
|
std::string value;
|
|
std::vector<yamal> vec_data;
|
|
ordered_map<yamal> map_data;
|
|
|
|
std::string pre_comment;
|
|
std::string inline_comment;
|
|
bool quoted = false;
|
|
bool inline_map = false;
|
|
|
|
// Mode checks
|
|
bool isScalar() const;
|
|
bool isVector() const;
|
|
bool isMap() const;
|
|
|
|
// Mode setters
|
|
void clearToScalar();
|
|
void clearToVector();
|
|
void clearToMap();
|
|
|
|
// Accessors
|
|
operator std::string() const;
|
|
operator int() const;
|
|
operator float() const;
|
|
operator bool() const;
|
|
|
|
yamal& operator=(const std::string& v);
|
|
yamal& operator=(int v);
|
|
yamal& operator=(float v);
|
|
yamal& operator=(bool b);
|
|
|
|
std::string asString() const;
|
|
int asInt() const;
|
|
float asFloat() const;
|
|
bool asBool() const;
|
|
|
|
// Comment accessors
|
|
const std::string& getComment() const;
|
|
yamal& setComment(const std::string& c);
|
|
yamal& appendComment(const std::string& c);
|
|
|
|
// Formatting
|
|
yamal& setQuoted(bool q = true);
|
|
yamal& setInline(bool in = true);
|
|
|
|
// Vector and map access
|
|
void push_back(const yamal& item);
|
|
yamal& operator[](size_t i);
|
|
yamal& operator[](const std::string& key);
|
|
|
|
std::vector<std::pair<std::string, yamal>> attributes() const;
|
|
|
|
// Serialization
|
|
std::string serialize(int indent = 0) const;
|
|
|
|
// Deserialization
|
|
void deserialize(const std::string& yamlText);
|
|
|
|
private:
|
|
bool isBoolLiteral() const;
|
|
bool isNumericLiteral() const;
|
|
bool isSafeUnquotedString() const;
|
|
};
|
|
|
|
} // namespace yamal_ns
|