diff --git a/google-apis-common/src/serde.rs b/google-apis-common/src/serde.rs index a34d4318ad..e7de0b1c4e 100644 --- a/google-apis-common/src/serde.rs +++ b/google-apis-common/src/serde.rs @@ -97,7 +97,7 @@ pub mod duration { } } - fn duration_to_string(duration: &Duration) -> String { + pub fn to_string(duration: &Duration) -> String { let seconds = duration.num_seconds(); let nanoseconds = (*duration - Duration::seconds(seconds)) .num_nanoseconds() @@ -121,7 +121,7 @@ pub mod duration { where S: serde::Serializer, { - s.serialize_str(&duration_to_string(value)) + s.serialize_str(&to_string(value)) } } @@ -142,12 +142,16 @@ pub mod urlsafe_base64 { pub struct Wrapper; + pub fn to_string(bytes: &Vec) -> String { + base64::encode_config(bytes, base64::URL_SAFE) + } + impl SerializeAs> for Wrapper { fn serialize_as(value: &Vec, s: S) -> Result where S: Serializer, { - s.serialize_str(&base64::encode_config(value, base64::URL_SAFE)) + s.serialize_str(&to_string(value)) } } @@ -162,6 +166,10 @@ pub mod urlsafe_base64 { } } +pub fn datetime_to_string(datetime: &chrono::DateTime) -> String { + datetime.to_rfc3339_opts(chrono::SecondsFormat::Millis, true) +} + #[cfg(test)] mod test { use super::{duration, urlsafe_base64}; diff --git a/src/generator/lib/util.py b/src/generator/lib/util.py index 5379c04a55..a9f789c3e7 100644 --- a/src/generator/lib/util.py +++ b/src/generator/lib/util.py @@ -1241,5 +1241,15 @@ def size_to_bytes(size): # end handle errors gracefully +def string_impl(p): + return { + "google-duration": "::client::serde::duration::to_string", + "byte": "::client::serde::urlsafe_base64::to_string", + "google-datetime": "::client::serde::datetime_to_string", + "date-time": "::client::serde::datetime_to_string", + "google-fieldmask": "(|x: &client::FieldMask| x.to_string())" + }.get(p.get("format"), "(|x: &dyn std::fmt::Display| x.to_string())") + + if __name__ == '__main__': raise AssertionError('For import only') diff --git a/src/generator/templates/api/lib/mbuild.mako b/src/generator/templates/api/lib/mbuild.mako index 1c970b828e..e6db099470 100644 --- a/src/generator/templates/api/lib/mbuild.mako +++ b/src/generator/templates/api/lib/mbuild.mako @@ -11,7 +11,7 @@ DELEGATE_PROPERTY_NAME, struct_type_bounds_s, scope_url_to_variant, re_find_replacements, ADD_PARAM_FN, ADD_PARAM_MEDIA_EXAMPLE, upload_action_fn, METHODS_RESOURCE, method_name_to_variant, size_to_bytes, method_default_scope, - is_repeated_property, setter_fn_name, ADD_SCOPE_FN, rust_doc_sanitize, items) + is_repeated_property, setter_fn_name, ADD_SCOPE_FN, rust_doc_sanitize, items, string_impl) def get_parts(part_prop): if not part_prop: @@ -534,6 +534,7 @@ match result { % for p in field_params: <% pname = 'self.' + property(p.name) # property identifier + to_string_impl = string_impl(p) %>\ ## parts can also be derived from the request, but we do that only if it's not set % if p.name == 'part' and request_value: @@ -556,15 +557,15 @@ match result { % if p.get('repeated', False): if ${pname}.len() > 0 { for f in ${pname}.iter() { - params.push(("${p.name}", f.to_string())); + params.push(("${p.name}", ${to_string_impl}(f))); } } % elif not is_required_property(p): - if let Some(value) = ${pname} { - params.push(("${p.name}", value.to_string())); + if let Some(value) = ${pname}.as_ref() { + params.push(("${p.name}", ${to_string_impl}(value))); } % else: - params.push(("${p.name}", ${pname}.to_string())); + params.push(("${p.name}", ${to_string_impl}(&${pname}))); % endif % endfor ## Additional params - may not overlap with optional params