1: <?php declare( strict_types = 1 );
2:
3: namespace Waves\Model;
4:
5: use Exception;
6: use Waves\Common\Base64String;
7: use Waves\Common\ExceptionCode;
8: use Waves\Common\JsonBase;
9: use Waves\Common\Value;
10:
11: class DataEntry extends JsonBase
12: {
13: /**
14: * @param string $key
15: * @param integer $type
16: * @param mixed $value
17: * @return DataEntry
18: */
19: static function build( string $key, int $type, $value = null ): DataEntry
20: {
21: if( $type === EntryType::DELETE )
22: $json = [ 'key' => $key, 'type' => null ];
23: else
24: if( !isset( $value ) )
25: throw new Exception( __FUNCTION__ . ' value expected but not set', ExceptionCode::UNEXPECTED );
26: else
27: if( $type === EntryType::BINARY )
28: $json = [ 'key' => $key, 'type' => 'binary', 'value' => Base64String::fromBytes( Value::as( $value )->asString() )->toString() ];
29: else
30: $json = [ 'key' => $key, 'type' => DataEntry::typeToString( $type ), 'value' => $value ];
31: return new DataEntry( Value::as( $json )->asJson() );
32: }
33:
34: static function binary( string $key, string $value ): DataEntry
35: {
36: return DataEntry::build( $key, EntryType::BINARY, $value );
37: }
38:
39: static function string( string $key, string $value ): DataEntry
40: {
41: return DataEntry::build( $key, EntryType::STRING, $value );
42: }
43:
44: static function int( string $key, int $value ): DataEntry
45: {
46: return DataEntry::build( $key, EntryType::INTEGER, $value );
47: }
48:
49: static function boolean( string $key, bool $value ): DataEntry
50: {
51: return DataEntry::build( $key, EntryType::BOOLEAN, $value );
52: }
53:
54: static function delete( string $key ): DataEntry
55: {
56: return DataEntry::build( $key, EntryType::DELETE );
57: }
58:
59: static function stringToType( string $stringType ): int
60: {
61: switch( $stringType )
62: {
63: case 'binary': return EntryType::BINARY;
64: case 'boolean': return EntryType::BOOLEAN;
65: case 'integer': return EntryType::INTEGER;
66: case 'string': return EntryType::STRING;
67: default: throw new Exception( __FUNCTION__ . ' failed to detect type `' . serialize( $stringType ) . '`', ExceptionCode::UNKNOWN_TYPE );
68: }
69: }
70:
71: static function typeToString( int $type ): string
72: {
73: switch( $type )
74: {
75: case EntryType::BINARY: return 'binary';
76: case EntryType::BOOLEAN: return 'boolean';
77: case EntryType::INTEGER: return 'integer';
78: case EntryType::STRING: return 'string';
79: default: throw new Exception( __FUNCTION__ . ' failed to detect type `' . serialize( $type ) . '`', ExceptionCode::UNKNOWN_TYPE );
80: }
81: }
82:
83: function key(): string { return $this->json->get( 'key' )->asString(); }
84:
85: function type(): int
86: {
87: if( !$this->json->exists( 'type' ) )
88: return EntryType::DELETE;
89: return $this->stringToType( $this->json->get( 'type' )->asString() );
90: }
91:
92: /**
93: * Returns value of native type
94: *
95: * @return bool|int|string|null
96: */
97: function value()
98: {
99: switch( $this->type() )
100: {
101: case EntryType::BINARY: return $this->json->get( 'value' )->asBase64Decoded();
102: case EntryType::BOOLEAN: return $this->json->get( 'value' )->asBoolean();
103: case EntryType::INTEGER: return $this->json->get( 'value' )->asInt();
104: case EntryType::STRING: return $this->json->get( 'value' )->asString();
105: case EntryType::DELETE: return null;
106: default: throw new Exception( __FUNCTION__ . ' failed to detect type `' . serialize( $this->type() ) . '`', ExceptionCode::UNKNOWN_TYPE ); // @codeCoverageIgnore
107: }
108: }
109:
110: function stringValue(): string
111: {
112: return Value::as( $this->value() )->asString();
113: }
114:
115: function intValue(): int
116: {
117: return Value::as( $this->value() )->asInt();
118: }
119:
120: function booleanValue(): bool
121: {
122: return Value::as( $this->value() )->asBoolean();
123: }
124:
125: function toProtobuf(): \Waves\Protobuf\DataTransactionData\DataEntry
126: {
127: $pb_DataEntry = new \Waves\Protobuf\DataTransactionData\DataEntry;
128: $pb_DataEntry->setKey( $this->key() );
129: switch( $this->type() )
130: {
131: case EntryType::BINARY: $pb_DataEntry->setBinaryValue( $this->json->get( 'value' )->asBase64Decoded() ); break;
132: case EntryType::BOOLEAN: $pb_DataEntry->setBoolValue( $this->json->get( 'value' )->asBoolean() ); break;
133: case EntryType::INTEGER: $pb_DataEntry->setIntValue( $this->json->get( 'value' )->asInt() ); break;
134: case EntryType::STRING: $pb_DataEntry->setStringValue( $this->json->get( 'value' )->asString() ); break;
135: case EntryType::DELETE: break;
136: default: throw new Exception( __FUNCTION__ . ' failed to detect type `' . serialize( $this->type() ) . '`', ExceptionCode::UNKNOWN_TYPE ); // @codeCoverageIgnore
137: }
138: return $pb_DataEntry;
139: }
140: }
141: