Open philippeitis opened 2 years ago
That would certainly be nice to have! And it would even be backwards compatible.
The implementation would probably have to use the schema information to build types to build a sibling structure like proposed here. I wonder if it could be made available through the returned structure itself.
For instance, if files().list()
returns a File
type, could File::FIELD::NextPagetoken
be a way to access it? That we we don't have even more types to deal with, hopefully eliminating the potential for clashes entirely.
The only obvious solution I can see that would allow for the proposed solution is using associated trait types:
trait Fields {
type Fields;
}
struct File {
id: String,
name: String,
}
trait ToParam {
fn to_param(&self) -> String;
}
mod fields {
use super::ToParam;
pub enum File {
Id,
Name
}
impl ToParam for File {
fn to_param(&self) -> String {
match self {
File::Id => "id",
File::Name => "name"
}.to_string()
}
}
}
impl Fields for File {
type Fields = fields::File;
}
fn main() {
println!("{}", <File as Fields>::Fields::Id.to_param());
}
This solution could use a separate module for the fields to avoid collisions wherever possible (the names can be further disambiguated by using the full method chain).
Your proposal of using File::FIELD::NextPageToken
syntax, which would quite nice (example: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ae62cc52907647b81a09d202ba7eaf4b) is not currently supported, per https://github.com/rust-lang/rust/issues/8995.
However, using the trait-based associated type approach would not prevent File::FIELD::NextPageToken
syntax in the future.
This looks good to me, and I think it would help tremendously to know exactly how to access a types fields, instead of associating them by naming scheme for example. The latter would of course work, too, i.e. struct File
has its field in fields::File
or something like that. Maybe both can be employed at the same time as well, leaving using the associated type optional, even for us - after all it ads complexity which might better be avoided or added later once it's clear it's worth the cost.
In any case, my suggestion is to go ahead with a minimal implementation that associates field enums by name, and optionally associate the struct and enums by trait in a follow-up.
It would be nice if the APIs provided an
include_field
API with definitions for fields that could be included. Given that all possible fields are known, it seems like it'd be possible to generate a field enum for each method, which includes all of the possible fields.This would be helpful for both discoverability (since this might not be the most well-known feature), and correctness (by only including fields which exist as enum variants, every
include_field
call would be correct, and we can guarantee that thefields
parameter syntax would be correct).Example usage (current):
Example usage (desired):