11use pyo3:: intern;
22use pyo3:: prelude:: * ;
33use pyo3:: types:: { PyDict , PyList , PyString } ;
4-
54use serde:: ser:: SerializeMap ;
65use serde:: Serialize ;
76
8- use crate :: build_tools:: SchemaDict ;
7+ use crate :: build_tools:: { py_error_type, SchemaDict } ;
8+ use crate :: definitions:: DefinitionsBuilder ;
99use crate :: serializers:: filter:: SchemaFilter ;
10+ use crate :: serializers:: shared:: { BuildSerializer , CombinedSerializer , PydanticSerializer , TypeSerializer } ;
1011
1112use super :: errors:: py_err_se_err;
12- use super :: infer:: { infer_serialize, infer_serialize_known, infer_to_python, infer_to_python_known} ;
13- use super :: ob_type:: ObType ;
1413use super :: Extra ;
1514
16- use super :: type_serializers:: function:: get_json_return_type;
17-
1815#[ derive( Debug , Clone ) ]
1916pub ( super ) struct ComputedFields ( Vec < ComputedField > ) ;
2017
2118impl ComputedFields {
22- pub fn new ( schema : & PyDict ) -> PyResult < Option < Self > > {
19+ pub fn new (
20+ schema : & PyDict ,
21+ config : Option < & PyDict > ,
22+ definitions : & mut DefinitionsBuilder < CombinedSerializer > ,
23+ ) -> PyResult < Option < Self > > {
2324 let py = schema. py ( ) ;
2425 if let Some ( computed_fields) = schema. get_as :: < & PyList > ( intern ! ( py, "computed_fields" ) ) ? {
2526 let computed_fields = computed_fields
2627 . iter ( )
27- . map ( ComputedField :: new)
28+ . map ( |field| ComputedField :: new ( field , config , definitions ) )
2829 . collect :: < PyResult < Vec < _ > > > ( ) ?;
2930 Ok ( Some ( Self ( computed_fields) ) )
3031 } else {
@@ -88,22 +89,28 @@ impl ComputedFields {
8889struct ComputedField {
8990 property_name : String ,
9091 property_name_py : Py < PyString > ,
91- return_ob_type : Option < ObType > ,
92+ serializer : CombinedSerializer ,
9293 alias : String ,
9394 alias_py : Py < PyString > ,
9495}
9596
9697impl ComputedField {
97- pub fn new ( schema : & PyAny ) -> PyResult < Self > {
98+ pub fn new (
99+ schema : & PyAny ,
100+ config : Option < & PyDict > ,
101+ definitions : & mut DefinitionsBuilder < CombinedSerializer > ,
102+ ) -> PyResult < Self > {
98103 let py = schema. py ( ) ;
99104 let schema: & PyDict = schema. downcast ( ) ?;
100105 let property_name: & PyString = schema. get_as_req ( intern ! ( py, "property_name" ) ) ?;
101- let return_ob_type = get_json_return_type ( schema) ?;
106+ let return_schema = schema. get_as_req ( intern ! ( py, "return_schema" ) ) ?;
107+ let serializer = CombinedSerializer :: build ( return_schema, config, definitions)
108+ . map_err ( |e| py_error_type ! ( "Computed field `{}`:\n {}" , property_name, e) ) ?;
102109 let alias_py: & PyString = schema. get_as ( intern ! ( py, "alias" ) ) ?. unwrap_or ( property_name) ;
103110 Ok ( Self {
104111 property_name : property_name. extract ( ) ?,
105112 property_name_py : property_name. into_py ( py) ,
106- return_ob_type ,
113+ serializer ,
107114 alias : alias_py. extract ( ) ?,
108115 alias_py : alias_py. into_py ( py) ,
109116 } )
@@ -124,11 +131,9 @@ impl ComputedField {
124131 if let Some ( ( next_include, next_exclude) ) = filter. key_filter ( property_name_py, include, exclude) ? {
125132 let next_value = model. getattr ( property_name_py) ?;
126133
127- // TODO fix include & exclude
128- let value = match self . return_ob_type {
129- Some ( ref ob_type) => infer_to_python_known ( ob_type, next_value, next_include, next_exclude, extra) ,
130- None => infer_to_python ( next_value, next_include, next_exclude, extra) ,
131- } ?;
134+ let value = self
135+ . serializer
136+ . to_python ( next_value, next_include, next_exclude, extra) ?;
132137 let key = match extra. by_alias {
133138 true => self . alias_py . as_ref ( py) ,
134139 false => property_name_py,
@@ -152,12 +157,13 @@ impl<'py> Serialize for ComputedFieldSerializer<'py> {
152157 let py = self . model . py ( ) ;
153158 let property_name_py = self . computed_field . property_name_py . as_ref ( py) ;
154159 let next_value = self . model . getattr ( property_name_py) . map_err ( py_err_se_err) ?;
155-
156- match self . computed_field . return_ob_type {
157- Some ( ref ob_type) => {
158- infer_serialize_known ( ob_type, next_value, serializer, self . include , self . exclude , self . extra )
159- }
160- None => infer_serialize ( next_value, serializer, self . include , self . exclude , self . extra ) ,
161- }
160+ let s = PydanticSerializer :: new (
161+ next_value,
162+ & self . computed_field . serializer ,
163+ self . include ,
164+ self . exclude ,
165+ self . extra ,
166+ ) ;
167+ s. serialize ( serializer)
162168 }
163169}
0 commit comments