Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
if data_type.doc:
doc = self.process_doc(data_type.doc, self._docf)
else:
doc = 'The {} struct'.format(fmt_class(data_type.name))
self.emit_wrapped_text(doc, prefix='/// ', width=120)
protocols = []
if not data_type.parent_type:
protocols.append('CustomStringConvertible')
with self.class_block(data_type, protocols=protocols):
for field in data_type.fields:
fdoc = self.process_doc(field.doc,
self._docf) if field.doc else undocumented
self.emit_wrapped_text(fdoc, prefix='/// ', width=120)
self.emit('public let {}: {}'.format(
fmt_var(field.name),
fmt_type(field.data_type),
))
self._generate_struct_init(namespace, data_type)
decl = 'open var' if not data_type.parent_type else 'open override var'
with self.block('{} description: String'.format(decl)):
cls = fmt_class(data_type.name) + 'Serializer'
self.emit('return "\\(SerializeUtil.prepareJSONForSerialization' +
'({}().serialize(self)))"'.format(cls))
self._generate_struct_class_serializer(namespace, data_type)
rtype = fmt_serial_type(route.result_data_type)
etype = fmt_serial_type(route.error_data_type)
self._maybe_generate_deprecation_warning(route)
with self.function_block('@discardableResult open func {}'.format(func_name),
args=self._func_args(arg_list, force_first=False),
return_type='{}<{}, {}>'.format(req_obj_name, rtype, etype)):
self.emit('let route = {}.{}'.format(fmt_class(namespace.name), func_name))
if is_struct_type(route.arg_data_type):
args = [(name, name) for name, _ in self._struct_init_args(route.arg_data_type)]
func_args += [('serverArgs', '{}({})'.format(arg_type, self._func_args(args)))]
self.emit('let serverArgs = {}({})'.format(arg_type, self._func_args(args)))
elif is_union_type(route.arg_data_type):
self.emit('let serverArgs = {}'.format(fmt_var(route.arg_data_type.name)))
if not is_void_type(route.arg_data_type):
return_args += [('serverArgs', 'serverArgs')]
return_args += client_args
txt = 'return client.request({})'.format(
self._func_args(return_args, not_init=True)
)
self.emit(txt)
self.emit()
def _generate_enumerated_subtype_serializer(self, namespace, # pylint: disable=unused-argument
data_type):
with self.block('switch value'):
for tags, subtype in data_type.get_all_subtypes_with_tags():
assert len(tags) == 1, tags
tag = tags[0]
tagvar = fmt_var(tag)
self.emit('case let {} as {}:'.format(
tagvar,
fmt_type(subtype)
))
with self.indent():
block_txt = 'for (k, v) in Serialization.getFields({}.serialize({}))'.format(
fmt_serial_obj(subtype),
tagvar,
)
with self.block(block_txt):
self.emit('output[k] = v')
self.emit('output[".tag"] = .str("{}")'.format(tag))
self.emit('default: fatalError("Tried to serialize unexpected subtype")')
def _generate_struct_class_serializer(self, namespace, data_type):
with self.serializer_block(data_type):
with self.serializer_func(data_type):
if not data_type.all_fields:
self.emit('let output = [String: JSON]()')
else:
intro = 'var' if data_type.has_enumerated_subtypes() else 'let'
self.emit("{} output = [ ".format(intro))
for field in data_type.all_fields:
self.emit('"{}": {}.serialize(value.{}),'.format(
field.name,
fmt_serial_obj(field.data_type),
fmt_var(field.name)
))
self.emit(']')
if data_type.has_enumerated_subtypes():
self._generate_enumerated_subtype_serializer(namespace, data_type)
self.emit('return .dictionary(output)')
with self.deserializer_func(data_type):
with self.block("switch json"):
dict_name = "let dict" if data_type.all_fields else "_"
self.emit("case .dictionary({}):".format(dict_name))
with self.indent():
if data_type.has_enumerated_subtypes():
self._generate_enumerated_subtype_deserializer(namespace, data_type)
else:
self._generate_struct_base_class_deserializer(namespace, data_type)
self.emit("default:")
def _generate_struct_init(self, namespace, data_type): # pylint: disable=unused-argument
# init method
args = self._struct_init_args(data_type)
if data_type.parent_type and not data_type.fields:
return
with self.function_block('public init', self._func_args(args)):
for field in data_type.fields:
v = fmt_var(field.name)
validator = self._determine_validator_type(field.data_type, v)
if validator:
self.emit('{}({})'.format(validator, v))
self.emit('self.{} = {}'.format(v, v))
if data_type.parent_type:
func_args = [(fmt_var(f.name),
fmt_var(f.name))
for f in data_type.parent_type.all_fields]
self.emit('super.init({})'.format(self._func_args(func_args)))
def _generate_struct_base_class_deserializer(self, namespace, data_type):
args = []
for field in data_type.all_fields:
var = fmt_var(field.name)
value = 'dict["{}"]'.format(field.name)
self.emit('let {} = {}.deserialize({} ?? {})'.format(
var,
fmt_serial_obj(field.data_type),
value,
fmt_default_value(namespace, field) if field.has_default else '.null'
))
args.append((var, var))
self.emit('return {}({})'.format(
fmt_class(data_type.name),
self._func_args(args)
))
def _docf(self, tag, val):
if tag == 'route':
if ':' in val:
val, version = val.split(':', 1)
version = int(version)
else:
version = 1
return fmt_func(val, version)
elif tag == 'field':
if '.' in val:
cls, field = val.split('.')
return ('{} in {}'.format(fmt_var(field),
fmt_class(cls)))
else:
return fmt_var(val)
elif tag in ('type', 'val', 'link'):
return val
else:
import pdb
pdb.set_trace()
return val
def _get_route_args(self, namespace, route):
data_type = route.arg_data_type
arg_type = fmt_type(data_type)
if is_struct_type(data_type):
arg_list = self._struct_init_args(data_type, namespace=namespace)
doc_list = [(fmt_var(f.name), self.process_doc(f.doc, self._docf)
if f.doc else undocumented) for f in data_type.fields if f.doc]
elif is_union_type(data_type):
arg_list = [(fmt_var(data_type.name), '{}.{}'.format(
fmt_class(namespace.name), fmt_class(data_type.name)))]
doc_list = [(fmt_var(data_type.name),
self.process_doc(data_type.doc, self._docf)
if data_type.doc else 'The {} union'.format(fmt_class(data_type.name)))]
else:
arg_list = [] if is_void_type(data_type) else [('request', arg_type)]
doc_list = []
return arg_list, doc_list
def _tag_type(self, data_type, field):
return "{}.{}".format(
fmt_class(data_type.name),
fmt_var(field.name)
)
def _struct_init_args(self, data_type, namespace=None): # pylint: disable=unused-argument
args = []
for field in data_type.all_fields:
name = fmt_var(field.name)
value = fmt_type(field.data_type)
data_type, nullable = unwrap_nullable(field.data_type)
if field.has_default:
if is_union_type(data_type):
default = '.{}'.format(fmt_var(field.default.tag_name))
else:
default = fmt_obj(field.default)
value += ' = {}'.format(default)
elif nullable:
value += ' = nil'
arg = (name, value)
args.append(arg)
return args