aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/config/domscheme.h
blob: 613850be014a7106512de5ca5af669f2081b9a06 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#pragma once

#include "config.h"

#include <util/generic/algorithm.h>
#include <util/generic/typetraits.h>
#include <util/stream/str.h>

struct TConfigTraits {
    using TValue = NConfig::TConfig;
    using TValueRef = const TValue*;
    using TConstValueRef = TValueRef;
    using TStringType = TString;

    // anyvalue defaults
    template <class T>
    static inline TValue Value(const T& t) {
        return TValue(NConfig::ConstructValue(t));
    }

    template <class T>
    static inline TValue Value(std::initializer_list<T> list) {
        NConfig::TArray result;
        for (const auto& t : list) {
            result.push_back(TValue(NConfig::ConstructValue(t)));
        }
        return TValue(NConfig::ConstructValue(std::move(result)));
    }

    static inline TConstValueRef Ref(const TValue& v) {
        return &v;
    }

    // common ops
    static inline bool IsNull(TConstValueRef v) {
        return v->IsNull();
    }

    static inline TString ToJson(TConstValueRef v) {
        TStringStream str;
        v->ToJson(str);
        return str.Str();
    }

    // struct ops
    static inline TConstValueRef GetField(TConstValueRef v, const TStringBuf& name) {
        return &(*v)[name];
    }

    // array ops
    static bool IsArray(TConstValueRef v) {
        return v->IsA<NConfig::TArray>();
    }

    using TArrayIterator = size_t;

    static inline TConstValueRef ArrayElement(TConstValueRef v, TArrayIterator n) {
        return &(*v)[n];
    }

    static inline size_t ArraySize(TConstValueRef v) {
        return v->GetArraySize();
    }

    static inline TArrayIterator ArrayBegin(TConstValueRef) {
        return 0;
    }

    static inline TArrayIterator ArrayEnd(TConstValueRef v) {
        return ArraySize(v);
    }

    // dict ops
    static bool IsDict(TConstValueRef v) {
        return v->IsA<NConfig::TDict>();
    }

    static inline TConstValueRef DictElement(TConstValueRef v, TStringBuf key) {
        return &(*v)[key];
    }

    static inline size_t DictSize(TConstValueRef v) {
        return v->Get<NConfig::TDict>().size();
    }

    using TDictIterator = NConfig::TDict::const_iterator;

    static inline TDictIterator DictBegin(TConstValueRef v) {
        return v->Get<NConfig::TDict>().begin();
    }

    static inline TDictIterator DictEnd(TConstValueRef v) {
        return v->Get<NConfig::TDict>().end();
    }

    static inline TStringBuf DictIteratorKey(TConstValueRef /*dict*/, const TDictIterator& it) {
        return it->first;
    }

    static inline TConstValueRef DictIteratorValue(TConstValueRef /*dict*/, const TDictIterator& it) {
        return &it->second;
    }

    // generic get
    template <typename T>
    static inline void Get(TConstValueRef v, T def, T& t) {
        t = v->As<T>(def);
    }

    static inline bool Get(TConstValueRef v, double def, double& t) {
        if (v->IsNumeric()) {
            t = v->As<double>(def);
            return true;
        }
        t = def;
        return false;
    }

    template <typename T>
    static inline void Get(TConstValueRef v, T& t) {
        t = v->As<T>();
    }

    template <typename T>
    static inline bool IsValidPrimitive(const T&, TConstValueRef v) {
        if (v->IsNull()) {
            return true;
        }

        try {
            v->As<T>();

            return true;
        } catch (const NConfig::TTypeMismatch&) {
        } catch (const TBadCastException&) {
        }

        return false;
    }

    template <class T>
    static inline void Set(TValueRef v, T&& t) {
        v->GetNonConstant<std::remove_const_t<std::remove_reference_t<T>>>() = t;
    }

    // validation ops
    static inline TVector<TString> GetKeys(TConstValueRef v) {
        TVector<TString> res;
        for (const auto& it : v->Get<NConfig::TDict>()) {
            res.push_back(it.first);
        }
        Sort(res.begin(), res.end());
        return res;
    }
};