blob: daabd225da80d5b2a81bd44c38743dbf8c25e927 [file] [log] [blame]
Wei-Yu Chenad55cb82022-02-15 20:07:01 +08001# SPDX-FileCopyrightText: 2020 The Magma Authors.
2# SPDX-FileCopyrightText: 2022 Open Networking Foundation <support@opennetworking.org>
3#
4# SPDX-License-Identifier: BSD-3-Clause
Wei-Yu Chen49950b92021-11-08 19:19:18 +08005
Wei-Yu Chen49950b92021-11-08 19:19:18 +08006from typing import Callable, Generic, Type, TypeVar
7
8import jsonpickle
9from orc8r.protos.redis_pb2 import RedisState
10
11T = TypeVar('T')
12
13
14class RedisSerde(Generic[T]):
15 """
16 typeval (str): str representing the type of object the serde can
17 de/serialize
18 serializer (function (T, int) -> str):
19 function called to serialize a value
20 deserializer (function (str) -> T):
21 function called to deserialize a value
22 """
23
24 def __init__(
25 self,
26 redis_type: str,
27 serializer: Callable[[T, int], str],
28 deserializer: Callable[[str], T],
29 ):
30 self.redis_type = redis_type
31 self.serializer = serializer
32 self.deserializer = deserializer
33
34 def serialize(self, msg: T, version: int = 1) -> str:
35 return self.serializer(msg, version)
36
37 def deserialize(self, serialized_obj: str) -> T:
38 return self.deserializer(serialized_obj)
39
40
41def get_proto_serializer() -> Callable[[T, int], str]:
42 """
43 Return a proto serializer that serializes the proto, adds the associated
44 version, and then serializes the RedisState proto to a string
45 """
46 def _serialize_proto(proto: T, version: int) -> str:
47 serialized_proto = proto.SerializeToString()
48 redis_state = RedisState(
49 serialized_msg=serialized_proto,
50 version=version,
51 is_garbage=False,
52 )
53 return redis_state.SerializeToString()
54 return _serialize_proto
55
56
57def get_proto_deserializer(proto_class: Type[T]) -> Callable[[str], T]:
58 """
59 Return a proto deserializer that takes in a proto type to deserialize
60 the serialized msg stored in the RedisState proto
61 """
62 def _deserialize_proto(serialized_rule: str) -> T:
63 proto_wrapper = RedisState()
64 proto_wrapper.ParseFromString(serialized_rule)
65 serialized_proto = proto_wrapper.serialized_msg
66 proto = proto_class()
67 proto.ParseFromString(serialized_proto)
68 return proto
69 return _deserialize_proto
70
71
72def get_json_serializer() -> Callable[[T, int], str]:
73 """
74 Return a json serializer that serializes the json msg, adds the
75 associated version, and then serializes the RedisState proto to a string
76 """
77 def _serialize_json(msg: T, version: int) -> str:
78 serialized_msg = jsonpickle.encode(msg)
79 redis_state = RedisState(
80 serialized_msg=serialized_msg.encode('utf-8'),
81 version=version,
82 is_garbage=False,
83 )
84 return redis_state.SerializeToString()
85
86 return _serialize_json
87
88
89def get_json_deserializer() -> Callable[[str], T]:
90 """
91 Returns a json deserializer that deserializes the RedisState proto and
92 then deserializes the json msg
93 """
94 def _deserialize_json(serialized_rule: str) -> T:
95 proto_wrapper = RedisState()
96 proto_wrapper.ParseFromString(serialized_rule)
97 serialized_msg = proto_wrapper.serialized_msg
98 msg = jsonpickle.decode(serialized_msg.decode('utf-8'))
99 return msg
100
101 return _deserialize_json
102
103
104def get_proto_version_deserializer() -> Callable[[str], T]:
105 """
106 Return a proto deserializer that takes in a proto type to deserialize
107 the version number stored in the RedisState proto
108 """
109 def _deserialize_version(serialized_rule: str) -> T:
110 proto_wrapper = RedisState()
111 proto_wrapper.ParseFromString(serialized_rule)
112 return proto_wrapper.version
113 return _deserialize_version