1
1
import 'dart:convert' ;
2
2
3
+ import 'package:tbdex/src/http_client/models/exchange.dart' ;
3
4
import 'package:tbdex/src/protocol/models/close.dart' ;
4
5
import 'package:tbdex/src/protocol/models/message.dart' ;
5
6
import 'package:tbdex/src/protocol/models/offering.dart' ;
@@ -11,7 +12,97 @@ import 'package:tbdex/src/protocol/models/rfq.dart';
11
12
12
13
abstract class Parser {
13
14
static Message parseMessage (String rawMessage) {
14
- final jsonObject = jsonDecode (rawMessage) as Map <String , dynamic >? ;
15
+ final jsonObject = jsonDecode (rawMessage);
16
+
17
+ if (jsonObject is ! Map <String , dynamic >) {
18
+ throw Exception ('message must be a json object' );
19
+ }
20
+
21
+ return _parseMessageJson (jsonObject);
22
+ }
23
+
24
+ static Resource parseResource (String rawResource) {
25
+ final jsonObject = jsonDecode (rawResource);
26
+
27
+ if (jsonObject is ! Map <String , dynamic >) {
28
+ throw Exception ('resource must be a json object' );
29
+ }
30
+
31
+ return _parseResourceJson (jsonObject);
32
+ }
33
+
34
+ static Exchange parseExchange (String rawExchange) {
35
+ final jsonObject = jsonDecode (rawExchange);
36
+
37
+ if (jsonObject is ! Map <String , dynamic >) {
38
+ throw Exception ('exchange must be a json object' );
39
+ }
40
+
41
+ final exchange = jsonObject['data' ];
42
+
43
+ if (exchange is ! List <dynamic > || exchange.isEmpty) {
44
+ throw Exception ('exchange data is malformed or empty' );
45
+ }
46
+
47
+ final parsedMessages = < Message > [];
48
+ for (final messageJson in exchange) {
49
+ final message = _parseMessageJson (messageJson);
50
+ parsedMessages.add (message);
51
+ }
52
+
53
+ return parsedMessages;
54
+ }
55
+
56
+ static List <Exchange > parseExchanges (String rawExchanges) {
57
+ final jsonObject = jsonDecode (rawExchanges);
58
+
59
+ if (jsonObject is ! Map <String , dynamic >) {
60
+ throw Exception ('exchanges must be a json object' );
61
+ }
62
+
63
+ final exchanges = jsonObject['data' ];
64
+
65
+ if (exchanges is ! List <dynamic > || exchanges.isEmpty) {
66
+ throw Exception ('exchanges data is malformed or empty' );
67
+ }
68
+
69
+ final parsedExchanges = < Exchange > [];
70
+
71
+ for (final exchangeJson in exchanges) {
72
+ final parsedMessages = < Message > [];
73
+ for (final messageJson in exchangeJson) {
74
+ final message = _parseMessageJson (messageJson);
75
+ parsedMessages.add (message);
76
+ }
77
+ parsedExchanges.add (parsedMessages);
78
+ }
79
+
80
+ return parsedExchanges;
81
+ }
82
+
83
+ static List <Offering > parseOfferings (String rawOfferings) {
84
+ final jsonObject = jsonDecode (rawOfferings);
85
+
86
+ if (jsonObject is ! Map <String , dynamic >) {
87
+ throw Exception ('offerings must be a json object' );
88
+ }
89
+
90
+ final offerings = jsonObject['data' ];
91
+
92
+ if (offerings is ! List <dynamic > || offerings.isEmpty) {
93
+ throw Exception ('offerings data is malformed or empty' );
94
+ }
95
+
96
+ final parsedOfferings = < Offering > [];
97
+ for (final offeringJson in offerings) {
98
+ final offering = _parseResourceJson (offeringJson) as Offering ;
99
+ parsedOfferings.add (offering);
100
+ }
101
+
102
+ return parsedOfferings;
103
+ }
104
+
105
+ static Message _parseMessageJson (Map <String , dynamic > jsonObject) {
15
106
final messageKind = _getKindFromJson (jsonObject);
16
107
final matchedKind = MessageKind .values.firstWhere (
17
108
(kind) => kind.name == messageKind,
@@ -20,20 +111,19 @@ abstract class Parser {
20
111
21
112
switch (matchedKind) {
22
113
case MessageKind .rfq:
23
- return Rfq .fromJson (jsonObject ?? {} );
114
+ return Rfq .fromJson (jsonObject);
24
115
case MessageKind .quote:
25
- return Quote .fromJson (jsonObject ?? {} );
116
+ return Quote .fromJson (jsonObject);
26
117
case MessageKind .close:
27
- return Close .fromJson (jsonObject ?? {} );
118
+ return Close .fromJson (jsonObject);
28
119
case MessageKind .order:
29
- return Order .fromJson (jsonObject ?? {} );
120
+ return Order .fromJson (jsonObject);
30
121
case MessageKind .orderstatus:
31
- return OrderStatus .fromJson (jsonObject ?? {} );
122
+ return OrderStatus .fromJson (jsonObject);
32
123
}
33
124
}
34
125
35
- static Resource parseResource (String rawResource) {
36
- final jsonObject = jsonDecode (rawResource) as Map <String , dynamic >? ;
126
+ static Resource _parseResourceJson (Map <String , dynamic > jsonObject) {
37
127
final resourceKind = _getKindFromJson (jsonObject);
38
128
final matchedKind = ResourceKind .values.firstWhere (
39
129
(kind) => kind.name == resourceKind,
@@ -42,25 +132,28 @@ abstract class Parser {
42
132
43
133
switch (matchedKind) {
44
134
case ResourceKind .offering:
45
- return Offering .fromJson (jsonObject ?? {} );
135
+ return Offering .fromJson (jsonObject);
46
136
case ResourceKind .balance:
47
137
case ResourceKind .reputation:
48
138
throw UnimplementedError ();
49
139
}
50
140
}
51
141
52
- static String _getKindFromJson (Map <String , dynamic >? jsonObject) {
53
- if (jsonObject == null ) {
54
- throw Exception ('string is not a valid json object' );
142
+ static String _getKindFromJson (Map <String , dynamic > jsonObject) {
143
+ final metadata = jsonObject['metadata' ];
144
+
145
+ if (metadata is ! Map <String , dynamic > || metadata.isEmpty) {
146
+ throw Exception ('metadata is malformed or empty' );
55
147
}
56
148
57
- final metadata = jsonObject[ 'metadata' ] as Map < String , dynamic > ? ;
149
+ final kind = metadata[ 'kind' ] ;
58
150
59
- if (metadata == null ) {
60
- throw Exception ('metadata property is required' );
151
+ if (kind is ! String ) {
152
+ throw Exception (
153
+ 'kind property is required in metadata and must be a string' ,
154
+ );
61
155
}
62
156
63
- final kind = metadata['kind' ] as String ? ;
64
- return kind ?? (throw Exception ('kind property is required in metadata' ));
157
+ return kind;
65
158
}
66
159
}
0 commit comments