aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yson_pull/event.h
blob: c141b0688995bd7c6c246bd137cedf5c779c86bd (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
#pragma once

#include "cyson_enums.h"
#include "scalar.h"

#include <util/generic/strbuf.h>
#include <util/system/types.h>
#include <util/system/yassert.h>

namespace NYsonPull {
    //! A well-formed decoded YSON stream can be described by the following grammar: 
    //! 
    //! STREAM[node]          ::= begin_stream VALUE end_stream 
    //! STREAM[list_fragment] ::= begin_stream LIST_FRAGMENT end_stream 
    //! STREAM[map_fragment]  ::= begin_stream MAP_FRAGMENT end_stream 
    //! LIST_FRAGMENT         ::= { VALUE; } 
    //! MAP_FRAGMENT          ::= { KEY VALUE; } 
    //! KEY                   ::= key(String) 
    //! VALUE                 ::= VALUE_NOATTR | ATTRIBUTES VALUE_NOATTR 
    //! ATTRIBUTES            ::= begin_attributes MAP_FRAGMENT end_attributes 
    //! VALUE_NOATTR          ::= scalar(Scalar) | LIST | MAP 
    //! LIST                  ::= begin_list LIST_FRAGMENT end_list 
    //! MAP                   ::= begin_map MAP_FRAGMENT end_map 

    //! \brief YSON event type tag. Corresponds to YSON grammar. 
    enum class EEventType { 
        BeginStream = YSON_EVENT_BEGIN_STREAM,
        EndStream = YSON_EVENT_END_STREAM,
        BeginList = YSON_EVENT_BEGIN_LIST,
        EndList = YSON_EVENT_END_LIST,
        BeginMap = YSON_EVENT_BEGIN_MAP,
        EndMap = YSON_EVENT_END_MAP,
        BeginAttributes = YSON_EVENT_BEGIN_ATTRIBUTES,
        EndAttributes = YSON_EVENT_END_ATTRIBUTES,
        Key = YSON_EVENT_KEY,
        Scalar = YSON_EVENT_SCALAR,
    }; 

    //! \brief YSON event variant type. 
    class TEvent { 
        EEventType Type_;
        TScalar Value_;

    public: 
        //! \brief Construct a tag-only event. 
        explicit constexpr TEvent(EEventType type = EEventType::BeginStream)
            : Type_{type} {
        } 

        //! \brief Construct a tag+value event. 
        //! 
        //! Only \p EEventType::key is meaningful. 
        constexpr TEvent(EEventType type, const TScalar& value) 
            : Type_{type}
            , Value_{value} {
        } 

        //! \brief Construct a \p EEventType::scalar event. 
        explicit constexpr TEvent(const TScalar& value) 
            : Type_{EEventType::Scalar}
            , Value_{value} {
        } 

        EEventType Type() const {
            return Type_;
        } 

        //! \brief Get TScalar value. 
        //! 
        //! Undefined behaviour when event type is not \p EEventType::scalar. 
        const TScalar& AsScalar() const {
            Y_ASSERT(Type_ == EEventType::Scalar || Type_ == EEventType::Key);
            return Value_;
        } 

        //! \brief Get string value. 
        //! 
        //! Undefined behaviour when event type is not \p EEventType::key. 
        TStringBuf AsString() const {
            Y_ASSERT(Type_ == EEventType::Key || (Type_ == EEventType::Scalar && Value_.Type() == EScalarType::String));
            return Value_.AsString();
        } 
    }; 

}