blob: d8b01e1f65b4e00abe949c31a6bd1a49808f13c5 [file] [log] [blame]
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001"""
2Copyright 2020 The Magma Authors.
3
4This source code is licensed under the BSD-style license found in the
5LICENSE file in the root directory of this source tree.
6
7Unless required by applicable law or agreed to in writing, software
8distributed under the License is distributed on an "AS IS" BASIS,
9WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10See the License for the specific language governing permissions and
11limitations under the License.
12"""
13from typing import Callable, Generic, Type, TypeVar
14
15import jsonpickle
16from orc8r.protos.redis_pb2 import RedisState
17
18T = TypeVar('T')
19
20
21class RedisSerde(Generic[T]):
22 """
23 typeval (str): str representing the type of object the serde can
24 de/serialize
25 serializer (function (T, int) -> str):
26 function called to serialize a value
27 deserializer (function (str) -> T):
28 function called to deserialize a value
29 """
30
31 def __init__(
32 self,
33 redis_type: str,
34 serializer: Callable[[T, int], str],
35 deserializer: Callable[[str], T],
36 ):
37 self.redis_type = redis_type
38 self.serializer = serializer
39 self.deserializer = deserializer
40
41 def serialize(self, msg: T, version: int = 1) -> str:
42 return self.serializer(msg, version)
43
44 def deserialize(self, serialized_obj: str) -> T:
45 return self.deserializer(serialized_obj)
46
47
48def get_proto_serializer() -> Callable[[T, int], str]:
49 """
50 Return a proto serializer that serializes the proto, adds the associated
51 version, and then serializes the RedisState proto to a string
52 """
53 def _serialize_proto(proto: T, version: int) -> str:
54 serialized_proto = proto.SerializeToString()
55 redis_state = RedisState(
56 serialized_msg=serialized_proto,
57 version=version,
58 is_garbage=False,
59 )
60 return redis_state.SerializeToString()
61 return _serialize_proto
62
63
64def get_proto_deserializer(proto_class: Type[T]) -> Callable[[str], T]:
65 """
66 Return a proto deserializer that takes in a proto type to deserialize
67 the serialized msg stored in the RedisState proto
68 """
69 def _deserialize_proto(serialized_rule: str) -> T:
70 proto_wrapper = RedisState()
71 proto_wrapper.ParseFromString(serialized_rule)
72 serialized_proto = proto_wrapper.serialized_msg
73 proto = proto_class()
74 proto.ParseFromString(serialized_proto)
75 return proto
76 return _deserialize_proto
77
78
79def get_json_serializer() -> Callable[[T, int], str]:
80 """
81 Return a json serializer that serializes the json msg, adds the
82 associated version, and then serializes the RedisState proto to a string
83 """
84 def _serialize_json(msg: T, version: int) -> str:
85 serialized_msg = jsonpickle.encode(msg)
86 redis_state = RedisState(
87 serialized_msg=serialized_msg.encode('utf-8'),
88 version=version,
89 is_garbage=False,
90 )
91 return redis_state.SerializeToString()
92
93 return _serialize_json
94
95
96def get_json_deserializer() -> Callable[[str], T]:
97 """
98 Returns a json deserializer that deserializes the RedisState proto and
99 then deserializes the json msg
100 """
101 def _deserialize_json(serialized_rule: str) -> T:
102 proto_wrapper = RedisState()
103 proto_wrapper.ParseFromString(serialized_rule)
104 serialized_msg = proto_wrapper.serialized_msg
105 msg = jsonpickle.decode(serialized_msg.decode('utf-8'))
106 return msg
107
108 return _deserialize_json
109
110
111def get_proto_version_deserializer() -> Callable[[str], T]:
112 """
113 Return a proto deserializer that takes in a proto type to deserialize
114 the version number stored in the RedisState proto
115 """
116 def _deserialize_version(serialized_rule: str) -> T:
117 proto_wrapper = RedisState()
118 proto_wrapper.ParseFromString(serialized_rule)
119 return proto_wrapper.version
120 return _deserialize_version