1: <?php declare( strict_types = 1 );
2:
3: namespace Waves\Common;
4:
5: use Exception;
6: use Waves\Common\ExceptionCode;
7: use Waves\Transactions\Transaction;
8: use Waves\Account\Address;
9: use Waves\Model\Alias;
10: use Waves\Model\BalanceDetails;
11: use Waves\Model\DataEntry;
12: use Waves\Model\ScriptInfo;
13: use Waves\Model\BlockHeaders;
14: use Waves\Model\Balance;
15: use Waves\Model\AssetBalance;
16: use Waves\Model\AssetDetails;
17: use Waves\Model\AssetDistribution;
18: use Waves\Model\BlockchainRewards;
19: use Waves\Model\Block;
20: use Waves\Model\HistoryBalance;
21: use Waves\Model\ScriptDetails;
22: use Waves\Model\ScriptMeta;
23: use Waves\Model\LeaseInfo;
24: use Waves\Model\TransactionInfo;
25: use Waves\Model\TransactionWithStatus;
26: use Waves\Model\TransactionStatus;
27: use Waves\Model\Validation;
28: use Waves\Model\Votes;
29:
30: class Json
31: {
32: /**
33: * @var array<mixed, mixed>
34: */
35: private array $data;
36:
37: /**
38: * Json constructor
39: *
40: * @param array<mixed, mixed> $data
41: */
42: private function __construct( array $data = [] )
43: {
44: $this->data = $data;
45: }
46:
47: /**
48: * Json function constructor
49: *
50: * @param array<mixed, mixed> $data
51: * @return Json
52: */
53: static function as( array $data ): Json
54: {
55: return new Json( $data );
56: }
57:
58: static function emptyJson(): Json
59: {
60: return new Json;
61: }
62:
63: /**
64: * Gets native underlying data array
65: *
66: * @return array<mixed, mixed>
67: */
68: function data(): array
69: {
70: return $this->data;
71: }
72:
73: function toString(): string
74: {
75: $string = json_encode( $this->data );
76: if( $string === false )
77: throw new Exception( __FUNCTION__ . ' failed to encode internal array `' . serialize( $this->data) . '`', ExceptionCode::JSON_ENCODE );
78: return $string;
79: }
80:
81: /**
82: * Gets Value by key
83: *
84: * @param mixed $key
85: * @return Value
86: */
87: function get( $key ): Value
88: {
89: if( !isset( $this->data[$key] ) )
90: throw new Exception( __FUNCTION__ . ' failed to find key `' . $key . '`', ExceptionCode::KEY_MISSING );
91: return Value::as( $this->data[$key] );
92: }
93:
94: /**
95: * Gets Value by key or returns fallback value
96: *
97: * @param mixed $key
98: * @param mixed $value
99: * @return Value
100: */
101: function getOr( $key, $value ): Value
102: {
103: return $this->exists( $key ) ? $this->get( $key ) : Value::as( $value );
104: }
105:
106: /**
107: * Checks key exists
108: *
109: * @param mixed $key
110: * @return bool
111: */
112: function exists( $key ): bool
113: {
114: return isset( $this->data[$key] );
115: }
116:
117: /**
118: * Puts value by key
119: *
120: * @param mixed $key
121: * @param mixed $value
122: * @return Json
123: */
124: function put( $key, $value ): Json
125: {
126: $this->data[$key] = $value;
127: return $this;
128: }
129:
130: /**
131: * Gets a BlockHeaders value
132: *
133: * @return BlockHeaders
134: */
135: function asBlockHeaders(): BlockHeaders
136: {
137: return new BlockHeaders( $this );
138: }
139:
140: /**
141: * Gets a Balance value
142: *
143: * @return Balance
144: */
145: function asBalance(): Balance
146: {
147: return new Balance( $this );
148: }
149:
150: function asHistoryBalance(): HistoryBalance
151: {
152: return new HistoryBalance( $this );
153: }
154:
155: /**
156: * Gets a AssetBalance value
157: *
158: * @return AssetBalance
159: */
160: function asAssetBalance(): AssetBalance
161: {
162: return new AssetBalance( $this );
163: }
164:
165: function asAssetDetails(): AssetDetails
166: {
167: return new AssetDetails( $this );
168: }
169:
170: function asAssetDistribution(): AssetDistribution
171: {
172: return new AssetDistribution( $this );
173: }
174:
175: /**
176: * Gets a BalanceDetails value
177: *
178: * @return BalanceDetails
179: */
180: function asBalanceDetails(): BalanceDetails
181: {
182: return new BalanceDetails( $this );
183: }
184:
185: function asBlockchainRewards(): BlockchainRewards
186: {
187: return new BlockchainRewards( $this );
188: }
189:
190: function asBlock(): Block
191: {
192: return new Block( $this );
193: }
194:
195: /**
196: * Gets a DataEntry value
197: *
198: * @return DataEntry
199: */
200: function asDataEntry(): DataEntry
201: {
202: return new DataEntry( $this );
203: }
204:
205: function asLeaseInfo(): LeaseInfo
206: {
207: return new LeaseInfo( $this );
208: }
209:
210: function asScriptMeta(): ScriptMeta
211: {
212: return new ScriptMeta( $this );
213: }
214:
215: function asScriptInfo(): ScriptInfo
216: {
217: return new ScriptInfo( $this );
218: }
219:
220: function asScriptDetails(): ScriptDetails
221: {
222: return new ScriptDetails( $this );
223: }
224:
225: function asTransactionInfo(): TransactionInfo
226: {
227: return new TransactionInfo( $this );
228: }
229:
230: function asTransactionWithStatus(): TransactionWithStatus
231: {
232: return new TransactionWithStatus( $this );
233: }
234:
235: function asTransactionStatus(): TransactionStatus
236: {
237: return new TransactionStatus( $this );
238: }
239:
240: function asTransaction(): Transaction
241: {
242: return new Transaction( $this );
243: }
244:
245: function asValidation(): Validation
246: {
247: return new Validation( $this );
248: }
249:
250: function asVotes(): Votes
251: {
252: return new Votes( $this );
253: }
254:
255: /**
256: * Gets an array of BlockHeaders value
257: *
258: * @return array<int, BlockHeaders>
259: */
260: function asArrayBlockHeaders(): array
261: {
262: $array = [];
263: foreach( $this->data as $headers )
264: $array[] = Value::as( $headers )->asJson()->asBlockHeaders();
265: return $array;
266: }
267:
268: /**
269: * Gets an array of Block value
270: *
271: * @return array<int, Block>
272: */
273: function asArrayBlock(): array
274: {
275: $array = [];
276: foreach( $this->data as $headers )
277: $array[] = Value::as( $headers )->asJson()->asBlock();
278: return $array;
279: }
280:
281: /**
282: * Gets an array of LeaseInfo value
283: *
284: * @return array<int, LeaseInfo>
285: */
286: function asArrayLeaseInfo(): array
287: {
288: $array = [];
289: foreach( $this->data as $info )
290: $array[] = Value::as( $info )->asJson()->asLeaseInfo();
291: return $array;
292: }
293:
294: /**
295: * Gets an array value
296: *
297: * @return array<int, Address>
298: */
299: function asArrayAddress(): array
300: {
301: $array = [];
302: foreach( $this->data as $address )
303: $array[] = Address::fromString( Value::as( $address )->asString() );
304: return $array;
305: }
306:
307: /**
308: * Gets an array value
309: *
310: * @return array<int, Alias>
311: */
312: function asArrayAlias(): array
313: {
314: $array = [];
315: foreach( $this->data as $alias )
316: $array[] = Alias::fromFullAlias( Value::as( $alias )->asString() );
317: return $array;
318: }
319:
320: /**
321: * Gets an array value
322: *
323: * @return array<int, Balance>
324: */
325: function asArrayBalance(): array
326: {
327: $array = [];
328: foreach( $this->data as $balance )
329: $array[] = Value::as( $balance )->asJson()->asBalance();
330: return $array;
331: }
332:
333: /**
334: * Gets an array value
335: *
336: * @return array<int, HistoryBalance>
337: */
338: function asArrayHistoryBalance(): array
339: {
340: $array = [];
341: foreach( $this->data as $balance )
342: $array[] = Value::as( $balance )->asJson()->asHistoryBalance();
343: return $array;
344: }
345:
346: /**
347: * Gets an array value
348: *
349: * @return array<int, AssetBalance>
350: */
351: function asArrayAssetBalance(): array
352: {
353: $array = [];
354: foreach( $this->data as $assetBalance )
355: $array[] = Value::as( $assetBalance )->asJson()->asAssetBalance();
356: return $array;
357: }
358:
359: /**
360: * Gets an array value
361: *
362: * @return array<int, AssetDetails>
363: */
364: function asArrayAssetDetails(): array
365: {
366: $array = [];
367: foreach( $this->data as $assetDetails )
368: $array[] = Value::as( $assetDetails )->asJson()->asAssetDetails();
369: return $array;
370: }
371:
372: /**
373: * Gets an array value
374: *
375: * @return array<int, DataEntry>
376: */
377: function asArrayDataEntry(): array
378: {
379: $array = [];
380: foreach( $this->data as $data )
381: $array[] = Value::as( $data )->asJson()->asDataEntry();
382: return $array;
383: }
384:
385: /**
386: * Gets an array value
387: *
388: * @return array<int, TransactionWithStatus>
389: */
390: function asArrayTransactionWithStatus(): array
391: {
392: $array = [];
393: foreach( $this->data as $tx )
394: $array[] = Value::as( $tx )->asJson()->asTransactionWithStatus();
395: return $array;
396: }
397:
398: /**
399: * Gets an array value
400: *
401: * @return array<int, TransactionInfo>
402: */
403: function asArrayTransactionInfo(): array
404: {
405: $array = [];
406: foreach( $this->data as $tx )
407: $array[] = Value::as( $tx )->asJson()->asTransactionInfo();
408: return $array;
409: }
410:
411: /**
412: * @return array<int, TransactionStatus>
413: */
414: function asArrayTransactionStatus(): array
415: {
416: $array = [];
417: foreach( $this->data as $tx )
418: $array[] = Value::as( $tx )->asJson()->asTransactionStatus();
419: return $array;
420: }
421:
422: /**
423: * @return array<int, Transaction>
424: */
425: function asArrayTransaction(): array
426: {
427: $array = [];
428: foreach( $this->data as $tx )
429: $array[] = Value::as( $tx )->asJson()->asTransaction();
430: return $array;
431: }
432: }
433: