Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft: Rust Generator #4

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft

Conversation

chrisabruce
Copy link

This is a draft only, would like to see if you are interested in working together on porting the generator code to rust and making it install-able via Cargo.

I think the port could look very close to the python code. I can take a stab with broad brush strokes, but likely need your help to finalize it all.

Copy link
Owner

@dermesser dermesser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some general thoughts, by no means exhaustive :-)

// scopetype, scopeval = scopes_url_to_enum_val(discdoc['name'], method.get('scopes', [''])[-1])
// scope_enum = scopetype + '::' + scopeval

// if is_download:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this conditional is not very nice. We should find either enough common ground between upload/download/normal methods to properly share code or separate it into three different pieces. Without two dozen variables around them.

@@ -0,0 +1,593 @@
fn optionalize(name: &str, optional: bool) -> String {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest: The structure of the current Python script works and is structured in a somewhat useful way, but far away from a good and clear implementation -- due to my iterative process of starting with an actual schema and adding features over time.

We can definitely start from the general parts in the Python script, i.e.

  • Discover scopes and convert to enum type
  • Discover all parameter types and generate structs for them
    • Global parameters
    • Per-method parameters
  • Generate request/reply types
    • Types in schemas
    • Possibly ad-hoc types in the request/response sections of methods - this isn't implemented yet and I'm unclear if any API is using it
  • Generate services, recursively: Each service corresponds to an API Resource but a resource can have subresources.

So I think that this structure is a good idea, just that it's possible to find an easier, more clear way to generate the code for it.

And if we want to do it the proper® way, we might even look at generating TokenStreams directly instead of first generating text (à la this). It's definitely more difficult than to simply generate the code, but maybe also has its own merits, like strong typing.

}


fn fetch_discovery_base(url: &str, apis: &str) -> Vec<String> {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the entire fetch functionality can of course be more nicely encapsulated, from "script" style to "application" style.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure what you mean by the difference? Are you thinking creating a main Parser like struct and have the functions be impl?

// return frags
}

fn resolve_parameters(string: &str, paramsname: Option<String>) -> String {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is mostly a hack, I wonder if there is a better way to do this consistently

// raise e
}

fn generate_params_structs(resources: Vec<String>, super_name: Option<String>, global_params: Option<String>) -> Vec<String> {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this may benefit from being packed into a ParametersGenerator, which keeps state such as the global parameters and so on.

Then the whole parameter types generating business could be a subprogram.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.

}


fn parse_schema_types(name: &str, schema: &str, optional: bool, parents: Vec<String>) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can probably be tightened and split up into subroutines a bit, and compared to any official standards (if existing)

}


fn snake_to_camel(name: &str) -> String {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these functions should be replaced by a type RustIdentifier that ensures that we don't use API strings in Rust context interpolation.

@DavidS
Copy link
Contributor

DavidS commented May 30, 2022

Hi,

I just uploaded https://crates.io/crates/egads which might be useful for this.

@dermesser
Copy link
Owner

Indeed! That would make writing a Rust generator a lot easier to write.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants