Skip to content

Commit 3b1cbbc

Browse files
committed
Add missing file
1 parent 04fa18b commit 3b1cbbc

1 file changed

Lines changed: 131 additions & 0 deletions

File tree

  • betterproto2_compiler/src/betterproto2_compiler/known_types
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import typing
2+
3+
import betterproto2
4+
5+
from betterproto2_compiler.lib.google.protobuf import (
6+
ListValue as VanillaListValue,
7+
NullValue,
8+
Struct as VanillaStruct,
9+
Value as VanillaValue,
10+
)
11+
12+
13+
class Struct(VanillaStruct):
14+
# TODO typing
15+
@classmethod
16+
def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
17+
assert isinstance(value, dict)
18+
19+
fields: dict[str, Value] = {}
20+
21+
for key, val in value.items():
22+
fields[key] = Value.from_dict(val, ignore_unknown_fields=ignore_unknown_fields)
23+
24+
return cls(fields=fields)
25+
26+
# TODO typing
27+
def to_dict(
28+
self,
29+
*,
30+
output_format: betterproto2.OutputFormat = betterproto2.OutputFormat.PROTO_JSON,
31+
casing: betterproto2.Casing = betterproto2.Casing.CAMEL,
32+
include_default_values: bool = False,
33+
) -> dict[str, typing.Any] | typing.Any:
34+
# If the output format is PYTHON, we should have kept the wrapped type without building the real class
35+
assert output_format == betterproto2.OutputFormat.PROTO_JSON
36+
37+
return {
38+
key: value.to_dict(
39+
output_format=output_format, casing=casing, include_default_values=include_default_values
40+
)
41+
for key, value in self.fields.items()
42+
}
43+
44+
@staticmethod
45+
def from_wrapped(wrapped: betterproto2.JSON) -> "Struct":
46+
return Struct.from_dict(wrapped)
47+
48+
def to_wrapped(self) -> betterproto2.JSON:
49+
return self.to_dict()
50+
51+
52+
class Value(VanillaValue):
53+
# TODO typing
54+
@classmethod
55+
def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
56+
match value:
57+
case bool() as b:
58+
return cls(bool_value=b)
59+
case int() | float() as num:
60+
return cls(number_value=num)
61+
case str() as s:
62+
return cls(string_value=s)
63+
case list() as l:
64+
return cls(list_value=ListValue.from_dict(l))
65+
case dict() as d:
66+
return cls(struct_value=Struct.from_dict(d))
67+
case None:
68+
return cls(null_value=NullValue.NULL_VALUE)
69+
case _:
70+
raise ValueError(f"Unknown value type: {type(value)}")
71+
72+
# TODO typing
73+
def to_dict(
74+
self,
75+
*,
76+
output_format: betterproto2.OutputFormat = betterproto2.OutputFormat.PROTO_JSON,
77+
casing: betterproto2.Casing = betterproto2.Casing.CAMEL,
78+
include_default_values: bool = False,
79+
) -> dict[str, typing.Any] | typing.Any:
80+
# If the output format is PYTHON, we should have kept the wrapped type without building the real class
81+
assert output_format == betterproto2.OutputFormat.PROTO_JSON
82+
83+
match self:
84+
case Value(null_value=NullValue.NULL_VALUE):
85+
return None
86+
case Value(bool_value=bool(b)):
87+
return b
88+
case Value(number_value=int(num)) | Value(number_value=float(num)):
89+
return num
90+
case Value(string_value=str(s)):
91+
return s
92+
case Value(list_value=ListValue(values=l)):
93+
return [v.to_dict() for v in l]
94+
case Value(struct_value=Struct(fields=f)):
95+
return {k: v.to_dict() for k, v in f.items()}
96+
97+
raise ValueError("Invalid value")
98+
99+
@staticmethod
100+
def from_wrapped(wrapped: betterproto2.JSON) -> "Value":
101+
return Value.from_dict(wrapped)
102+
103+
def to_wrapped(self) -> betterproto2.JSON:
104+
return self.to_dict()
105+
106+
107+
class ListValue(VanillaListValue):
108+
# TODO typing
109+
@classmethod
110+
def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
111+
return cls(values=[Value.from_dict(v) for v in value])
112+
113+
# TODO typing
114+
def to_dict(
115+
self,
116+
*,
117+
output_format: betterproto2.OutputFormat = betterproto2.OutputFormat.PROTO_JSON,
118+
casing: betterproto2.Casing = betterproto2.Casing.CAMEL,
119+
include_default_values: bool = False,
120+
) -> dict[str, typing.Any] | typing.Any:
121+
# If the output format is PYTHON, we should have kept the wrapped type without building the real class
122+
assert output_format == betterproto2.OutputFormat.PROTO_JSON
123+
124+
return [value.to_dict() for value in self.values]
125+
126+
@staticmethod
127+
def from_wrapped(wrapped: list[betterproto2.JSON]) -> "ListValue":
128+
return ListValue.from_dict(wrapped)
129+
130+
def to_wrapped(self) -> list[betterproto2.JSON]:
131+
return self.to_dict()

0 commit comments

Comments
 (0)