def _default_value(self, field): if isinstance(field.data_type, ir.Nullable): return u'None' elif ir.is_numeric_type(ir.unwrap_aliases(field.data_type)[0]): return field.default elif isinstance(field.default, ir.TagRef): default_variant = None for variant in field.default.union_data_type.all_fields: if variant.name == field.default.tag_name: default_variant = variant if default_variant is None: raise RuntimeError( 'ERROR: didn\'t find matching variant of {}: {}'.format( field.data_type.name, field.default.tag_name)) return u'{}::{}'.format( self._rust_type(field.default.union_data_type), self.enum_variant_name(default_variant)) elif isinstance(field.data_type, ir.Boolean): if field.default: return u'true' else: return u'false' elif isinstance(field.data_type, ir.String): if not field.default: return u'String::new()' else: return u'"{}".to_owned()'.format(field.default) else: print(u'WARNING: unhandled default value {}'.format(field.default)) print(u' in field: {}'.format(field)) if isinstance(field.data_type, ir.Alias): print(u' unwrapped alias: {}'.format( ir.unwrap_aliases(field.data_type)[0])) return field.default
def _generate_alias_definition(self, namespace, alias): # type: (ApiNamespace, Alias) -> None unwrapped_dt, _ = unwrap_aliases(alias) if is_user_defined_type(unwrapped_dt): # If the alias is to a composite type, we want to alias the # generated class as well. self.emit('{} = {}'.format( alias.name, class_name_for_data_type(alias.data_type, namespace)))
def _generate_alias_definition(self, namespace, alias): v = generate_validator_constructor(namespace, alias.data_type) if alias.doc: self.emit_wrapped_text(self.process_doc(alias.doc, self._docf), prefix='# ') self.emit('{}_validator = {}'.format(alias.name, v)) unwrapped_dt, _ = unwrap_aliases(alias) if is_user_defined_type(unwrapped_dt): # If the alias is to a composite type, we want to alias the # generated class as well. self.emit('{} = {}'.format( alias.name, class_name_for_data_type(alias.data_type, namespace)))
def _generate_alias_definition(self, namespace, alias): v = generate_validator_constructor(namespace, alias.data_type) if alias.doc: self.emit_wrapped_text( self.process_doc(alias.doc, self._docf), prefix='# ') self.emit('{}_validator = {}'.format(alias.name, v)) unwrapped_dt, _ = unwrap_aliases(alias) if is_user_defined_type(unwrapped_dt): # If the alias is to a composite type, we want to alias the # generated class as well. self.emit('{} = {}'.format( alias.name, class_name_for_data_type(alias.data_type, namespace)))
def _impl_serde_for_union(self, union): type_name = self.enum_name(union) with self._impl_deserialize(type_name): self.emit(u'// union deserializer') self.emit(u'use serde::de::{self, MapAccess, Visitor};') self.emit(u'struct EnumVisitor;') with self.block(u'impl<\'de> Visitor<\'de> for EnumVisitor'): self.emit(u'type Value = {};'.format(type_name)) with self.emit_rust_function_def( u'expecting', [u'&self', u'f: &mut ::std::fmt::Formatter<\'_>'], u'::std::fmt::Result'): self.emit(u'f.write_str("a {} structure")'.format( union.name)) with self.emit_rust_function_def( u'visit_map<V: MapAccess<\'de>>', [u'self', u'mut map: V'], u'Result<Self::Value, V::Error>'): with self.block(u'let tag: &str = match map.next_key()?', after=';'): self.emit(u'Some(".tag") => map.next_value()?,') self.emit( u'_ => return Err(de::Error::missing_field(".tag"))' ) with self.block(u'match tag'): for field in union.all_fields: if field.catch_all: # Handle the 'Other' variant at the end. continue variant_name = self.enum_variant_name(field) ultimate_type = ir.unwrap(field.data_type)[0] if isinstance(field.data_type, ir.Void): with self.block(u'"{}" =>'.format(field.name)): self.emit( u'crate::eat_json_fields(&mut map)?;') self.emit(u'Ok({}::{})'.format( type_name, variant_name)) elif isinstance(ultimate_type, ir.Struct) \ and not ultimate_type.has_enumerated_subtypes(): if isinstance( ir.unwrap_aliases(field.data_type)[0], ir.Nullable): # A nullable here means we might have more fields that can be # deserialized into the inner type, or we might have nothing, # meaning None. if not ultimate_type.all_required_fields: raise RuntimeError( '{}.{}: an optional struct with no' ' required fields is ambiguous'. format(union.name, field.name)) self.emit( u'"{}" => Ok({}::{}({}::internal_deserialize_opt(' u'map, true)?)),'.format( field.name, type_name, variant_name, self._rust_type(ultimate_type))) else: self.emit( u'"{}" => Ok({}::{}({}::internal_deserialize(map)?)),' .format( field.name, type_name, variant_name, self._rust_type(field.data_type))) else: with self.block(u'"{}" =>'.format(field.name)): with self.block(u'match map.next_key()?'): self.emit( u'Some("{}") => Ok({}::{}(map.next_value()?)),' .format(field.name, type_name, variant_name)) if isinstance( ir.unwrap_aliases( field.data_type)[0], ir.Nullable): # if it's null, the field can be omitted entirely self.emit( u'None => Ok({}::{}(None)),'. format(type_name, variant_name)) else: self.emit( u'None => Err(' u'de::Error::missing_field("{}")),' .format(field.name)) self.emit( u'_ => Err(de::Error::unknown_field(' u'tag, VARIANTS))') if not union.closed: with self.block(u'_ =>'): self.emit( u'crate::eat_json_fields(&mut map)?;') self.emit(u'Ok({}::Other)'.format(type_name)) else: self.emit( u'_ => Err(de::Error::unknown_variant(tag, VARIANTS))' ) self.generate_multiline_list( list(u'"{}"'.format(field.name) for field in union.all_fields), before='const VARIANTS: &[&str] = &', after=';', delim=(u'[', u']'), ) self.emit( u'deserializer.deserialize_struct("{}", VARIANTS, EnumVisitor)' .format(union.name)) self.emit() with self._impl_serialize(type_name): self.emit(u'// union serializer') if len(union.all_fields) == 1 and union.all_fields[0].catch_all: # special case: an open union with no variants defined. self.emit(u'#![allow(unused_variables)]') self.emit( u'Err(::serde::ser::Error::custom("cannot serialize an open union with ' u'no defined variants"))') else: self.emit(u'use serde::ser::SerializeStruct;') with self.block(u'match *self'): for field in union.all_fields: if field.catch_all: # Handle the 'Other' variant at the end. continue variant_name = self.enum_variant_name(field) if isinstance(field.data_type, ir.Void): with self.block(u'{}::{} =>'.format( type_name, variant_name)): self.emit(u'// unit') self.emit( u'let mut s = serializer.serialize_struct("{}", 1)?;' .format(union.name)) self.emit(u's.serialize_field(".tag", "{}")?;'. format(field.name)) self.emit(u's.end()') else: ultimate_type = ir.unwrap(field.data_type)[0] needs_x = not (isinstance(field.data_type, ir.Struct) and not field.data_type.all_fields) ref_x = 'ref x' if needs_x else '_' with self.block(u'{}::{}({}) =>'.format( type_name, variant_name, ref_x)): if self.is_enum_type(ultimate_type): # Inner type is a union or polymorphic struct; need to always # emit another nesting level. self.emit( u'// union or polymporphic struct') self.emit( u'let mut s = serializer.serialize_struct("{}", 2)?;' .format(union.name)) self.emit( u's.serialize_field(".tag", "{}")?;'. format(field.name)) self.emit( u's.serialize_field("{}", x)?;'.format( field.name)) self.emit(u's.end()') elif isinstance( ir.unwrap_aliases(field.data_type)[0], ir.Nullable): self.emit( u'// nullable (struct or primitive)') # If it's nullable and the value is None, just emit the tag and # nothing else, otherwise emit the fields directly at the same # level. num_fields = 1 if ir.is_primitive_type(ultimate_type) \ else len(ultimate_type.all_fields) + 1 self.emit( u'let n = if x.is_some() {{ {} }} else {{ 1 }};' .format(num_fields + 1)) self.emit( u'let mut s = serializer.serialize_struct("{}", n)?;' .format(union.name)) self.emit( u's.serialize_field(".tag", "{}")?;'. format(field.name)) with self.block(u'if let Some(ref x) = x'): if ir.is_primitive_type(ultimate_type): self.emit( u's.serialize_field("{}", &x)?;' .format(field.name)) else: self.emit( u'x.internal_serialize::<S>(&mut s)?;' ) self.emit(u's.end()') elif isinstance(ultimate_type, ir.Struct): self.emit(u'// struct') self.emit( u'let mut s = serializer.serialize_struct("{}", {})?;' .format( union.name, len(ultimate_type.all_fields) + 1)) self.emit( u's.serialize_field(".tag", "{}")?;'. format(field.name)) if ultimate_type.all_fields: self.emit( u'x.internal_serialize::<S>(&mut s)?;' ) self.emit(u's.end()') else: self.emit(u'// primitive') self.emit( u'let mut s = serializer.serialize_struct("{}", 2)?;' .format(union.name)) self.emit( u's.serialize_field(".tag", "{}")?;'. format(field.name)) self.emit( u's.serialize_field("{}", x)?;'.format( field.name)) self.emit(u's.end()') if not union.closed: self.emit( u'{}::Other => Err(::serde::ser::Error::custom(' u'"cannot serialize \'Other\' variant"))'.format( type_name)) self.emit()
def _impl_serde_for_polymorphic_struct(self, struct): type_name = self.enum_name(struct) with self._impl_deserialize(type_name): self.emit(u'// polymorphic struct deserializer') self.emit(u'use serde::de::{self, MapAccess, Visitor};') self.emit(u'struct EnumVisitor;') with self.block(u'impl<\'de> Visitor<\'de> for EnumVisitor'): self.emit(u'type Value = {};'.format(type_name)) with self.emit_rust_function_def( u'expecting', [u'&self', u'f: &mut ::std::fmt::Formatter<\'_>'], u'::std::fmt::Result'): self.emit(u'f.write_str("a {} structure")'.format( struct.name)) with self.emit_rust_function_def( u'visit_map<V: MapAccess<\'de>>', [u'self', u'mut map: V'], u'Result<Self::Value, V::Error>'): with self.block(u'let tag = match map.next_key()?', after=';'): self.emit(u'Some(".tag") => map.next_value()?,') self.emit( u'_ => return Err(de::Error::missing_field(".tag"))' ) with self.block(u'match tag'): for subtype in struct.get_enumerated_subtypes(): variant_name = self.enum_variant_name(subtype) if isinstance(subtype.data_type, ir.Void): self.emit(u'"{}" => Ok({}::{}),'.format( subtype.name, type_name, variant_name)) elif isinstance(ir.unwrap_aliases(subtype.data_type)[0], ir.Struct) \ and not subtype.data_type.has_enumerated_subtypes(): self.emit( u'"{}" => Ok({}::{}({}::internal_deserialize(map)?)),' .format( subtype.name, type_name, variant_name, self._rust_type(subtype.data_type))) else: with self.block(u'"{}" =>'.format( subtype.name)): with self.block( u'if map.next_key()? != Some("{}")' .format(subtype.name)): self.emit( u'Err(de::Error::missing_field("{}"));' .format(subtype.name)) self.emit(u'Ok({}::{}(map.next_value()?))'. format(type_name, variant_name)) if struct.is_catch_all(): with self.block(u'_ =>'): # TODO(wfraser): it'd be cool to grab any fields in the parent, # which are common to all variants, and stick them in the # '_Unknown' enum vaiant. # For now, just consume them and return a nullary variant. self.emit( u'crate::eat_json_fields(&mut map)?;') self.emit( u'Ok({}::_Unknown)'.format(type_name)) else: self.emit( u'_ => Err(de::Error::unknown_variant(tag, VARIANTS))' ) self.generate_multiline_list(list( u'"{}"'.format(subtype.name) for field in struct.get_enumerated_subtypes()), before='const VARIANTS: &[&str] = &', after=';', delim=(u'[', u']')) self.emit( u'deserializer.deserialize_struct("{}", VARIANTS, EnumVisitor)' .format(struct.name)) self.emit() with self._impl_serialize(type_name): self.emit(u'// polymorphic struct serializer') self.emit(u'use serde::ser::SerializeStruct;') with self.block(u'match *self'): for subtype in struct.get_enumerated_subtypes(): variant_name = self.enum_variant_name(subtype) with self.block(u'{}::{}(ref x) =>'.format( type_name, variant_name)): self.emit( u'let mut s = serializer.serialize_struct("{}", {})?;' .format(type_name, len(subtype.data_type.all_fields) + 1)) self.emit(u's.serialize_field(".tag", "{}")?;'.format( subtype.name)) for field in subtype.data_type.all_fields: self.emit( u's.serialize_field("{}", &x.{})?;'.format( field.name, self.field_name(field))) self.emit(u's.end()') if struct.is_catch_all(): self.emit( u'{}::_Unknown => Err(::serde::ser::Error::custom("cannot serialize ' u'unknown variant"))'.format(type_name)) self.emit()
def _impl_serde_for_struct(self, struct): """ Emit internal_deserialize() and possibly internal_deserialize_opt(). internal_deserialize[_opt] takes a map and deserializes it into the struct. It reads the fields in whatever order; missing fields will be given their default value, or an error returned if they have no default. Errors will also be raised if a field is present more than once. The _opt deserializer returns a None if it reads exactly zero map keys, and is used for cases where the JSON has a tag, but omits all the fields to signify a null value. It is only emitted for types which have at least one required field, because if all fields are optional, there's no way to differentiate between a null value and one where all fields are default. """ type_name = self.struct_name(struct) field_list_name = u'{}_FIELDS'.format(fmt_shouting_snake(struct.name)) self.generate_multiline_list( list(u'"{}"'.format(field.name) for field in struct.all_fields), before='const {}: &[&str] = &'.format(field_list_name), after=';', delim=(u'[', u']')) # Only emit the _opt deserializer if there are required fields. optional = len(struct.all_required_fields) > 0 with self._impl_struct(struct): if optional: # Convenience wrapper around _opt for the more common case where the struct is # NOT optional. with self.emit_rust_function_def( u'internal_deserialize<\'de, V: ::serde::de::MapAccess<\'de>>', [u'map: V'], u'Result<{}, V::Error>'.format(type_name), access=u'pub(crate)'): self.emit(u'Self::internal_deserialize_opt(map, false)' u'.map(Option::unwrap)') self.emit() else: self.emit(u'// no _opt deserializer') with self.emit_rust_function_def( (u'internal_deserialize_opt' if optional else u'internal_deserialize') + u'<\'de, V: ::serde::de::MapAccess<\'de>>', [u'mut map: V'] + ([u'optional: bool'] if optional else []), (u'Result<Option<{}>, V::Error>' if optional else u'Result<{}, V::Error>').format(type_name), access=u'pub(crate)'): for field in struct.all_fields: self.emit(u'let mut field_{} = None;'.format( self.field_name(field))) if optional: self.emit(u'let mut nothing = true;') with self.block( u'while let Some(key) = map.next_key::<&str>()?'): if optional: self.emit(u'nothing = false;') with self.block(u'match key'): for field in struct.all_fields: field_name = self.field_name(field) with self.block(u'"{}" =>'.format(field.name)): with self.block( u'if field_{}.is_some()'.format( field_name)): self.emit( u'return Err(::serde::de::Error::duplicate_field(' u'"{}"));'.format(field.name)) self.emit( u'field_{} = Some(map.next_value()?);'. format(field_name)) with self.block(u'_ =>'): self.emit(u'// unknown field allowed and ignored') self.emit( u'map.next_value::<::serde_json::Value>()?;') if optional: with self.block(u'if optional && nothing'): self.emit(u'return Ok(None);') with self.block(u'let result = {}'.format(type_name), delim=(u'{', u'};')): for field in struct.all_fields: field_name = self.field_name(field) if isinstance(field.data_type, ir.Nullable): self.emit(u'{}: field_{},'.format( field_name, field_name)) elif field.has_default: if isinstance(field.data_type, ir.String) \ and not field.default: self.emit( u'{}: field_{}.unwrap_or_else(String::new),' .format(field_name, field_name)) elif ir.is_primitive_type( ir.unwrap_aliases(field.data_type)[0]): self.emit( u'{}: field_{}.unwrap_or({}),'.format( field_name, field_name, self._default_value(field))) else: self.emit( u'{}: field_{}.unwrap_or_else(|| {}),'. format(field_name, field_name, self._default_value(field))) else: self.emit( u'{}: field_{}.ok_or_else(|| ' u'::serde::de::Error::missing_field("{}"))?,'. format(field_name, field_name, field.name)) if optional: self.emit(u'Ok(Some(result))') else: self.emit(u'Ok(result)') if struct.all_fields: self.emit() with self.emit_rust_function_def( u'internal_serialize<S: ::serde::ser::Serializer>', [u'&self', u's: &mut S::SerializeStruct'], u'Result<(), S::Error>', access=u'pub(crate)'): self.emit(u'use serde::ser::SerializeStruct;') self.generate_multiline_list(list( u's.serialize_field("{}", &self.{})'.format( field.name, self.field_name(field)) for field in struct.all_fields), delim=(u'', u''), sep='?;', skip_last_sep=True) self.emit() with self._impl_deserialize(self.struct_name(struct)): self.emit(u'// struct deserializer') self.emit(u'use serde::de::{MapAccess, Visitor};') self.emit(u'struct StructVisitor;') with self.block(u'impl<\'de> Visitor<\'de> for StructVisitor'): self.emit(u'type Value = {};'.format(type_name)) with self.emit_rust_function_def( u'expecting', [u'&self', u'f: &mut ::std::fmt::Formatter<\'_>'], u'::std::fmt::Result'): self.emit(u'f.write_str("a {} struct")'.format( struct.name)) with self.emit_rust_function_def( u'visit_map<V: MapAccess<\'de>>', [u'self', u'map: V'], u'Result<Self::Value, V::Error>'): self.emit( u'{}::internal_deserialize(map)'.format(type_name)) self.emit( u'deserializer.deserialize_struct("{}", {}, StructVisitor)'. format(struct.name, field_list_name)) self.emit() with self._impl_serialize(type_name): self.emit(u'// struct serializer') self.emit(u'use serde::ser::SerializeStruct;') if not struct.all_fields: self.emit( u'serializer.serialize_struct("{}", 0)?.end()'.format( struct.name)) else: self.emit( u'let mut s = serializer.serialize_struct("{}", {})?;'. format(struct.name, len(struct.all_fields))) self.emit(u'self.internal_serialize::<S>(&mut s)?;') self.emit(u's.end()') self.emit()