github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/runtime/msg.go (about)

     1  package runtime
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  )
     9  
    10  // Msg methods don't return errors because they can be used not only at startup.
    11  // If runtime functions need to validate message at startup, they must do it by themselves.
    12  type Msg interface {
    13  	fmt.Stringer
    14  	Type() MsgType
    15  	Bool() bool
    16  	Int() int64
    17  	Float() float64
    18  	Str() string
    19  	List() []Msg
    20  	Map() map[string]Msg
    21  }
    22  
    23  type MsgType uint8
    24  
    25  const (
    26  	UnknownMsgType MsgType = 0
    27  	BoolMsgType    MsgType = 1
    28  	IntMsgType     MsgType = 2
    29  	FloatMsgType   MsgType = 3
    30  	StrMsgType     MsgType = 4
    31  	ListMsgType    MsgType = 5
    32  	MapMsgType     MsgType = 6
    33  )
    34  
    35  // Empty
    36  
    37  type emptyMsg struct{}
    38  
    39  func (emptyMsg) String() string      { return "<empty>" }
    40  func (emptyMsg) Type() MsgType       { return UnknownMsgType }
    41  func (emptyMsg) Bool() bool          { return false }
    42  func (emptyMsg) Int() int64          { return 0 }
    43  func (emptyMsg) Float() float64      { return 0 }
    44  func (emptyMsg) Str() string         { return "" }
    45  func (emptyMsg) List() []Msg         { return nil }
    46  func (emptyMsg) Map() map[string]Msg { return nil }
    47  
    48  // Int
    49  
    50  type IntMsg struct {
    51  	emptyMsg
    52  	v int64
    53  }
    54  
    55  func (msg IntMsg) Type() MsgType                { return IntMsgType }
    56  func (msg IntMsg) Int() int64                   { return msg.v }
    57  func (msg IntMsg) String() string               { return strconv.Itoa(int(msg.v)) }
    58  func (msg IntMsg) MarshalJSON() ([]byte, error) { return []byte(msg.String()), nil }
    59  
    60  func NewIntMsg(n int64) IntMsg {
    61  	return IntMsg{
    62  		emptyMsg: emptyMsg{},
    63  		v:        n,
    64  	}
    65  }
    66  
    67  // Float
    68  
    69  type FloatMsg struct {
    70  	emptyMsg
    71  	v float64
    72  }
    73  
    74  func (msg FloatMsg) Type() MsgType                { return FloatMsgType }
    75  func (msg FloatMsg) Float() float64               { return msg.v }
    76  func (msg FloatMsg) String() string               { return fmt.Sprint(msg.v) }
    77  func (msg FloatMsg) MarshalJSON() ([]byte, error) { return []byte(msg.String()), nil }
    78  
    79  func NewFloatMsg(n float64) FloatMsg {
    80  	return FloatMsg{
    81  		emptyMsg: emptyMsg{},
    82  		v:        n,
    83  	}
    84  }
    85  
    86  // Str
    87  
    88  type StrMsg struct {
    89  	emptyMsg
    90  	v string
    91  }
    92  
    93  func (msg StrMsg) Type() MsgType  { return StrMsgType }
    94  func (msg StrMsg) Str() string    { return msg.v }
    95  func (msg StrMsg) String() string { return msg.v }
    96  func (msg StrMsg) MarshalJSON() ([]byte, error) {
    97  	// Escape special characters in the string before marshaling
    98  	jsonString, err := json.Marshal(msg.String())
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  	return jsonString, nil
   103  }
   104  
   105  func NewStrMsg(s string) StrMsg {
   106  	return StrMsg{
   107  		emptyMsg: emptyMsg{},
   108  		v:        s,
   109  	}
   110  }
   111  
   112  // Bool
   113  
   114  type BoolMsg struct {
   115  	emptyMsg
   116  	v bool
   117  }
   118  
   119  func (msg BoolMsg) Type() MsgType                { return BoolMsgType }
   120  func (msg BoolMsg) Bool() bool                   { return msg.v }
   121  func (msg BoolMsg) String() string               { return strconv.FormatBool(msg.v) }
   122  func (msg BoolMsg) MarshalJSON() ([]byte, error) { return []byte(msg.String()), nil }
   123  
   124  func NewBoolMsg(b bool) BoolMsg {
   125  	return BoolMsg{
   126  		emptyMsg: emptyMsg{},
   127  		v:        b,
   128  	}
   129  }
   130  
   131  // List
   132  type ListMsg struct {
   133  	emptyMsg
   134  	v []Msg
   135  }
   136  
   137  func (msg ListMsg) Type() MsgType { return ListMsgType }
   138  func (msg ListMsg) List() []Msg   { return msg.v }
   139  func (msg ListMsg) String() string {
   140  	bb, err := msg.MarshalJSON()
   141  	if err != nil {
   142  		panic(err)
   143  	}
   144  	return string(bb)
   145  }
   146  func (msg ListMsg) MarshalJSON() ([]byte, error) { return json.Marshal(msg.v) }
   147  
   148  func NewListMsg(v ...Msg) ListMsg {
   149  	return ListMsg{
   150  		emptyMsg: emptyMsg{},
   151  		v:        v,
   152  	}
   153  }
   154  
   155  // Map
   156  type MapMsg struct {
   157  	emptyMsg
   158  	v map[string]Msg
   159  }
   160  
   161  func (msg MapMsg) Type() MsgType       { return MapMsgType }
   162  func (msg MapMsg) Map() map[string]Msg { return msg.v }
   163  func (msg MapMsg) MarshalJSON() ([]byte, error) {
   164  	jsonData, err := json.Marshal(msg.v)
   165  	if err != nil {
   166  		panic(err)
   167  	}
   168  
   169  	jsonString := string(jsonData)
   170  	jsonString = strings.ReplaceAll(jsonString, ":", ": ")
   171  	jsonString = strings.ReplaceAll(jsonString, ",", ", ")
   172  
   173  	return []byte(jsonString), nil
   174  }
   175  func (msg MapMsg) String() string {
   176  	b, err := msg.MarshalJSON()
   177  	if err != nil {
   178  		panic(err)
   179  	}
   180  	return string(b)
   181  }
   182  
   183  func NewMapMsg(m map[string]Msg) MapMsg {
   184  	return MapMsg{
   185  		emptyMsg: emptyMsg{},
   186  		v:        m,
   187  	}
   188  }