Beispiel #1
0
 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
Beispiel #2
0
 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)))
Beispiel #3
0
 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)))
Beispiel #4
0
 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)))
Beispiel #5
0
 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)))
Beispiel #6
0
 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()
Beispiel #7
0
 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()
Beispiel #8
0
    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()