changeset 4:95fca1b07ef5

Generate cleaner rust code
author Lewin Bormann <lbo@spheniscida.de>
date Sat, 17 Oct 2020 10:56:24 +0200
parents 09ee80214be1
children e0856ff450bb
files generate/generate.py manual_demo/Cargo.lock manual_demo/Cargo.toml manual_demo/src/main.rs
diffstat 4 files changed, 43 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/generate/generate.py	Sat Oct 17 10:39:19 2020 +0200
+++ b/generate/generate.py	Sat Oct 17 10:56:24 2020 +0200
@@ -20,11 +20,14 @@
 }
 '''
 
+def replace_keywords(name):
+    return {
+            'type': ('typ', 'type'),
+    }.get(name, name)
 
 def capitalize_first(name):
     return name[0].upper() + name[1:]
 
-
 def snake_case(name):
     def r(c):
         if c.islower():
@@ -35,6 +38,20 @@
 
 
 def type_of_property(name, prop):
+    """Translate a JSON schema type into Rust types.
+
+    Arguments:
+        name: Name of the property. If the property is an object with fixed fields, generate a struct with this name.
+        prop: A JSON object from a discovery document representing a type.
+
+    Returns:
+        type (string|tuple), structs (list of dicts)
+
+        where type is a string representing a Rust type, or a tuple where the first element is a Rust type
+        and the second element is a comment detailing the use of the field.
+        The list of dicts returned as structs are any structs that need to be separately implemented and that
+        the generated struct (if it was a struct) depends on.
+    """
     typ = ''
     comment = ''
     structs = []
@@ -52,11 +69,18 @@
                         subtyp, comment = subtyp
                     else:
                         comment = None
+                    cleaned_pn = replace_keywords(pn)
+                    if type(cleaned_pn) is tuple:
+                        jsonname = cleaned_pn[1]
+                        cleaned_pn = snake_case(cleaned_pn[0])
+                    else:
+                        jsonname = pn
+                        cleaned_pn = snake_case(cleaned_pn)
                     struct['fields'].append({
                         'name':
-                        snake_case(pn),
+                        cleaned_pn,
                         'attr':
-                        '#[serde(rename = "{}")]'.format(pn),
+                        '#[serde(rename = "{}")]'.format(jsonname),
                         'typ':
                         subtyp,
                         'comment':
@@ -91,7 +115,7 @@
                 if prop['format'] == 'float':
                     return ('String', 'f32'), structs
                 if prop['format'] == 'date-time':
-                    return 'Time', structs
+                    return 'DateTime<Utc>', structs
             return 'String', structs
         if prop['type'] == 'boolean':
             return 'bool', structs
@@ -120,7 +144,11 @@
 
     modname = (discdoc['id'] + '_types').replace(':', '_')
     with open(path.join('gen', modname + '.rs'), 'w') as f:
-        f.write('use serde::{Deserialize, Serialize};')
+        f.writelines([
+            'use serde::{Deserialize, Serialize};\n',
+            'use chrono::{DateTime, Utc};\n',
+            'use std::collections::HashMap;\n'
+            ])
         for s in structs:
             f.write(chevron.render(ResourceStructTmpl, s))
 
--- a/manual_demo/Cargo.lock	Sat Oct 17 10:39:19 2020 +0200
+++ b/manual_demo/Cargo.lock	Sat Oct 17 10:56:24 2020 +0200
@@ -399,6 +399,7 @@
 name = "manual_demo"
 version = "0.1.0"
 dependencies = [
+ "chrono",
  "hyper",
  "hyper-rustls",
  "serde",
--- a/manual_demo/Cargo.toml	Sat Oct 17 10:39:19 2020 +0200
+++ b/manual_demo/Cargo.toml	Sat Oct 17 10:56:24 2020 +0200
@@ -8,10 +8,10 @@
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-yup-oauth2 = "~4"
-serde_json = "~1.0"
-serde = "~1.0"
-tokio = { version = "~0.2", features = ["full"] }
+chrono = "~0.4"
 hyper = "~0.13"
 hyper-rustls = "~0.20"
-
+serde = "~1.0"
+serde_json = "~1.0"
+tokio = { version = "~0.2", features = ["full"] }
+yup-oauth2 = "~4"
--- a/manual_demo/src/main.rs	Sat Oct 17 10:39:19 2020 +0200
+++ b/manual_demo/src/main.rs	Sat Oct 17 10:56:24 2020 +0200
@@ -1,5 +1,9 @@
 // A manual client for a Google API (e.g. Drive), to test what makes sense and what doesn't.
 
+mod drive_v3_types;
+
+use drive_v3_types as drive;
+
 use yup_oauth2::InstalledFlowAuthenticator;
 use std::string::String;
 use std::str::FromStr;