From da6f32b1de3b11b7359a1e0c922532db4e95e216 Mon Sep 17 00:00:00 2001 From: Carlos O'Ryan Date: Mon, 2 Dec 2024 12:15:59 +0000 Subject: [PATCH] impl(generator): better blockquote handling (#346) Rust treats any blockquote as a Rust code sample, unless it has the `norust` tag. Furthermore, `cargo test` will try to compile these code samples. This is all very good, but we generate the documentation comments from the Probobuf (or OpenAPI) comments, which may and do include blockquotes that are not Rust code. This change handles a few more blockquote types. We really need to parse the Markdown comments to handle all possible cases, but this can handle the most urgent cases. --- generator/internal/language/rust.go | 70 ++++- generator/internal/language/rust_test.go | 102 +++++++ .../rust/gclient/golden/iam/v1/src/model.rs | 76 ++--- .../rust/gclient/golden/location/src/model.rs | 4 +- .../rust/gclient/golden/module/rpc/mod.rs | 62 ++-- .../rust/gclient/golden/module/type/mod.rs | 32 +- .../rust/gclient/golden/type/src/model.rs | 32 +- .../testdata/rust/openapi/golden/src/model.rs | 120 ++++---- src/gax/src/error/rpc/generated/mod.rs | 62 ++-- src/generated/cloud/location/src/model.rs | 4 +- src/generated/iam/v1/src/model.rs | 76 ++--- src/generated/type/src/model.rs | 284 +++++++++++------- 12 files changed, 595 insertions(+), 329 deletions(-) diff --git a/generator/internal/language/rust.go b/generator/internal/language/rust.go index 2a9fc3ea..013af0ca 100644 --- a/generator/internal/language/rust.go +++ b/generator/internal/language/rust.go @@ -609,21 +609,69 @@ func (*RustCodec) ToCamel(symbol string) string { return rustEscapeKeyword(strcase.ToLowerCamel(symbol)) } +// TODO(#92) - protect all quotes with `norust` +// TODO(#30) - convert protobuf links to Rusty links. +// +// Blockquotes require special treatment for Rust. By default, Rust assumes +// blockquotes contain compilable Rust code samples. To override the default +// the blockquote must be marked with "```norust". The proto comments have +// many blockquotes that do not follow this convention (nor should they). +// +// This function handles some easy cases of blockquotes, but a full treatment +// requires parsing of the comments. The CommonMark [spec] includes some +// difficult examples. +// +// [spec]: https://spec.commonmark.org/0.13/#block-quotes func (*RustCodec) FormatDocComments(documentation string) []string { - inBlockQuote := false - ss := strings.Split(documentation, "\n") - for i := range ss { - if strings.HasSuffix(ss[i], "```") { - if !inBlockQuote { - ss[i] = ss[i] + "norust" + inBlockquote := false + blockquotePrefix := "" + + var results []string + for _, line := range strings.Split(documentation, "\n") { + if inBlockquote { + switch { + case line == "```": + inBlockquote = false + results = append(results, "```") + case strings.HasPrefix(line, blockquotePrefix): + results = append(results, strings.TrimPrefix(line, blockquotePrefix)) + default: + inBlockquote = false + results = append(results, "```") + results = append(results, line) + } + } else { + switch { + case line == "```": + results = append(results, "```norust") + inBlockquote = true + case strings.HasPrefix(line, " "): + inBlockquote = true + blockquotePrefix = " " + results = append(results, "```norust") + results = append(results, strings.TrimPrefix(line, blockquotePrefix)) + case strings.HasPrefix(line, " > "): + inBlockquote = true + blockquotePrefix = " > " + results = append(results, "```norust") + results = append(results, strings.TrimPrefix(line, blockquotePrefix)) + case strings.HasPrefix(line, "> "): + inBlockquote = true + blockquotePrefix = "> " + results = append(results, "```norust") + results = append(results, strings.TrimPrefix(line, blockquotePrefix)) + default: + results = append(results, line) } - inBlockQuote = !inBlockQuote } - ss[i] = fmt.Sprintf("/// %s", ss[i]) - // nit: remove the trailing whitespace, this is unsightly. - ss[i] = strings.TrimRightFunc(ss[i], unicode.IsSpace) } - return ss + if inBlockquote { + results = append(results, "```") + } + for i, line := range results { + results[i] = strings.TrimRightFunc(fmt.Sprintf("/// %s", line), unicode.IsSpace) + } + return results } func (c *RustCodec) projectRoot() string { diff --git a/generator/internal/language/rust_test.go b/generator/internal/language/rust_test.go index bcaed1fa..b7950b77 100644 --- a/generator/internal/language/rust_test.go +++ b/generator/internal/language/rust_test.go @@ -939,6 +939,108 @@ func TestRust_FormatDocCommentsBullets(t *testing.T) { } } +func TestRust_FormatDocCommentsImplicitBlockQuote(t *testing.T) { + input := ` +Blockquotes come in many forms. They can start with a leading '> ', as in: + +> Block quote style 1 +> Continues 1 - style 1 +> Continues 2 - style 1 +> Continues 3 - style 1 + +They can start with 3 spaces and then '> ', as in: + + > Block quote style 2 + > Continues 1 - style 2 + > Continues 2 - style 2 + > Continues 3 - style 2 + +Or they can start with just 4 spaces: + + Block quote style 3 + Continues 1 - style 3 + Continues 2 - style 3 + Continues 3 - style 3 + +Note that four spaces and a leading '> ' makes the '> ' prefix part of the +block: + + > Block quote with arrow. + > Continues 1 - with arrow + > Continues 2 - with arrow + Continues 3 - with arrow + +` + + want := []string{ + "///", + "/// Blockquotes come in many forms. They can start with a leading '> ', as in:", + "///", + "/// ```norust", + "/// Block quote style 1", + "/// Continues 1 - style 1", + "/// Continues 2 - style 1", + "/// Continues 3 - style 1", + "/// ```", + "///", + "/// They can start with 3 spaces and then '> ', as in:", + "///", + "/// ```norust", + "/// Block quote style 2", + "/// Continues 1 - style 2", + "/// Continues 2 - style 2", + "/// Continues 3 - style 2", + "/// ```", + "///", + "/// Or they can start with just 4 spaces:", + "///", + "/// ```norust", + "/// Block quote style 3", + "/// Continues 1 - style 3", + "/// Continues 2 - style 3", + "/// Continues 3 - style 3", + "/// ```", + "///", + "/// Note that four spaces and a leading '> ' makes the '> ' prefix part of the", + "/// block:", + "///", + "/// ```norust", + "/// > Block quote with arrow.", + "/// > Continues 1 - with arrow", + "/// > Continues 2 - with arrow", + "/// Continues 3 - with arrow", + "/// ```", + "///", + "///", + } + + c := &RustCodec{} + got := c.FormatDocComments(input) + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("mismatch in FormatDocComments (-want, +got)\n:%s", diff) + } +} + +func TestRust_FormatDocCommentsImplicitBlockQuoteClosing(t *testing.T) { + input := `Blockquotes can appear at the end of the comment: + + they should have a closing element.` + + want := []string{ + "/// Blockquotes can appear at the end of the comment:", + "///", + "/// ```norust", + "/// they should have a closing element.", + "/// ```", + } + + c := &RustCodec{} + got := c.FormatDocComments(input) + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("mismatch in FormatDocComments (-want, +got)\n:%s", diff) + } +} + func TestRust_MessageNames(t *testing.T) { message := &api.Message{ Name: "Replication", diff --git a/generator/testdata/rust/gclient/golden/iam/v1/src/model.rs b/generator/testdata/rust/gclient/golden/iam/v1/src/model.rs index 86447a93..2cf44cf5 100755 --- a/generator/testdata/rust/gclient/golden/iam/v1/src/model.rs +++ b/generator/testdata/rust/gclient/golden/iam/v1/src/model.rs @@ -437,41 +437,43 @@ impl Binding { /// /// Example Policy with multiple AuditConfigs: /// +/// ```norust +/// { +/// "audit_configs": [ /// { -/// "audit_configs": [ +/// "service": "allServices", +/// "audit_log_configs": [ /// { -/// "service": "allServices", -/// "audit_log_configs": [ -/// { -/// "log_type": "DATA_READ", -/// "exempted_members": [ -/// "user:jose@example.com" -/// ] -/// }, -/// { -/// "log_type": "DATA_WRITE" -/// }, -/// { -/// "log_type": "ADMIN_READ" -/// } +/// "log_type": "DATA_READ", +/// "exempted_members": [ +/// "user:jose@example.com" /// ] /// }, /// { -/// "service": "sampleservice.googleapis.com", -/// "audit_log_configs": [ -/// { -/// "log_type": "DATA_READ" -/// }, -/// { -/// "log_type": "DATA_WRITE", -/// "exempted_members": [ -/// "user:aliya@example.com" -/// ] -/// } +/// "log_type": "DATA_WRITE" +/// }, +/// { +/// "log_type": "ADMIN_READ" +/// } +/// ] +/// }, +/// { +/// "service": "sampleservice.googleapis.com", +/// "audit_log_configs": [ +/// { +/// "log_type": "DATA_READ" +/// }, +/// { +/// "log_type": "DATA_WRITE", +/// "exempted_members": [ +/// "user:aliya@example.com" /// ] /// } /// ] /// } +/// ] +/// } +/// ``` /// /// For sampleservice, this policy enables DATA_READ, DATA_WRITE and ADMIN_READ /// logging. It also exempts `jose@example.com` from DATA_READ logging, and @@ -510,19 +512,21 @@ impl AuditConfig { /// Provides the configuration for logging a type of permissions. /// Example: /// +/// ```norust +/// { +/// "audit_log_configs": [ /// { -/// "audit_log_configs": [ -/// { -/// "log_type": "DATA_READ", -/// "exempted_members": [ -/// "user:jose@example.com" -/// ] -/// }, -/// { -/// "log_type": "DATA_WRITE" -/// } +/// "log_type": "DATA_READ", +/// "exempted_members": [ +/// "user:jose@example.com" /// ] +/// }, +/// { +/// "log_type": "DATA_WRITE" /// } +/// ] +/// } +/// ``` /// /// This enables 'DATA_READ' and 'DATA_WRITE' logging, while exempting /// jose@example.com from DATA_READ logging. diff --git a/generator/testdata/rust/gclient/golden/location/src/model.rs b/generator/testdata/rust/gclient/golden/location/src/model.rs index f5a776bf..331f42d5 100755 --- a/generator/testdata/rust/gclient/golden/location/src/model.rs +++ b/generator/testdata/rust/gclient/golden/location/src/model.rs @@ -123,7 +123,9 @@ pub struct Location { /// Cross-service attributes for the location. For example /// - /// {"cloud.googleapis.com/region": "us-east1"} + /// ```norust + /// {"cloud.googleapis.com/region": "us-east1"} + /// ``` #[serde(skip_serializing_if = "std::collections::HashMap::is_empty")] pub labels: std::collections::HashMap, diff --git a/generator/testdata/rust/gclient/golden/module/rpc/mod.rs b/generator/testdata/rust/gclient/golden/module/rpc/mod.rs index 5268c695..114c1ced 100755 --- a/generator/testdata/rust/gclient/golden/module/rpc/mod.rs +++ b/generator/testdata/rust/gclient/golden/module/rpc/mod.rs @@ -19,25 +19,29 @@ /// Example of an error when contacting the "pubsub.googleapis.com" API when it /// is not enabled: /// -/// { "reason": "API_DISABLED" -/// "domain": "googleapis.com" -/// "metadata": { -/// "resource": "projects/123", -/// "service": "pubsub.googleapis.com" -/// } -/// } +/// ```norust +/// { "reason": "API_DISABLED" +/// "domain": "googleapis.com" +/// "metadata": { +/// "resource": "projects/123", +/// "service": "pubsub.googleapis.com" +/// } +/// } +/// ``` /// /// This response indicates that the pubsub.googleapis.com API is not enabled. /// /// Example of an error that is returned when attempting to create a Spanner /// instance in a region that is out of stock: /// -/// { "reason": "STOCKOUT" -/// "domain": "spanner.googleapis.com", -/// "metadata": { -/// "availableRegions": "us-central1,us-east2" -/// } -/// } +/// ```norust +/// { "reason": "STOCKOUT" +/// "domain": "spanner.googleapis.com", +/// "metadata": { +/// "availableRegions": "us-central1,us-east2" +/// } +/// } +/// ``` #[serde_with::serde_as] #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] @@ -336,21 +340,27 @@ pub mod bad_request { /// /// Consider the following: /// - /// message CreateContactRequest { - /// message EmailAddress { - /// enum Type { - /// TYPE_UNSPECIFIED = 0; - /// HOME = 1; - /// WORK = 2; - /// } + /// ```norust + /// message CreateContactRequest { + /// message EmailAddress { + /// enum Type { + /// TYPE_UNSPECIFIED = 0; + /// HOME = 1; + /// WORK = 2; + /// } + /// ``` /// - /// optional string email = 1; - /// repeated EmailType type = 2; - /// } + /// ```norust + /// optional string email = 1; + /// repeated EmailType type = 2; + /// } + /// ``` /// - /// string full_name = 1; - /// repeated EmailAddress email_addresses = 2; - /// } + /// ```norust + /// string full_name = 1; + /// repeated EmailAddress email_addresses = 2; + /// } + /// ``` /// /// In this example, in proto `field` could take one of the following values: /// diff --git a/generator/testdata/rust/gclient/golden/module/type/mod.rs b/generator/testdata/rust/gclient/golden/module/type/mod.rs index 695c5b93..9b25ff0f 100755 --- a/generator/testdata/rust/gclient/golden/module/type/mod.rs +++ b/generator/testdata/rust/gclient/golden/module/type/mod.rs @@ -20,27 +20,35 @@ /// /// Example (Comparison): /// -/// title: "Summary size limit" -/// description: "Determines if a summary is less than 100 chars" -/// expression: "document.summary.size() < 100" +/// ```norust +/// title: "Summary size limit" +/// description: "Determines if a summary is less than 100 chars" +/// expression: "document.summary.size() < 100" +/// ``` /// /// Example (Equality): /// -/// title: "Requestor is owner" -/// description: "Determines if requestor is the document owner" -/// expression: "document.owner == request.auth.claims.email" +/// ```norust +/// title: "Requestor is owner" +/// description: "Determines if requestor is the document owner" +/// expression: "document.owner == request.auth.claims.email" +/// ``` /// /// Example (Logic): /// -/// title: "Public documents" -/// description: "Determine whether the document should be publicly visible" -/// expression: "document.type != 'private' && document.type != 'internal'" +/// ```norust +/// title: "Public documents" +/// description: "Determine whether the document should be publicly visible" +/// expression: "document.type != 'private' && document.type != 'internal'" +/// ``` /// /// Example (Data Manipulation): /// -/// title: "Notification string" -/// description: "Create a notification string with a timestamp." -/// expression: "'New message received at ' + string(document.create_time)" +/// ```norust +/// title: "Notification string" +/// description: "Create a notification string with a timestamp." +/// expression: "'New message received at ' + string(document.create_time)" +/// ``` /// /// The exact variables and functions that may be referenced within an expression /// are determined by the service that evaluates it. See the service diff --git a/generator/testdata/rust/gclient/golden/type/src/model.rs b/generator/testdata/rust/gclient/golden/type/src/model.rs index 8bd66b05..6d5f0509 100755 --- a/generator/testdata/rust/gclient/golden/type/src/model.rs +++ b/generator/testdata/rust/gclient/golden/type/src/model.rs @@ -20,27 +20,35 @@ /// /// Example (Comparison): /// -/// title: "Summary size limit" -/// description: "Determines if a summary is less than 100 chars" -/// expression: "document.summary.size() < 100" +/// ```norust +/// title: "Summary size limit" +/// description: "Determines if a summary is less than 100 chars" +/// expression: "document.summary.size() < 100" +/// ``` /// /// Example (Equality): /// -/// title: "Requestor is owner" -/// description: "Determines if requestor is the document owner" -/// expression: "document.owner == request.auth.claims.email" +/// ```norust +/// title: "Requestor is owner" +/// description: "Determines if requestor is the document owner" +/// expression: "document.owner == request.auth.claims.email" +/// ``` /// /// Example (Logic): /// -/// title: "Public documents" -/// description: "Determine whether the document should be publicly visible" -/// expression: "document.type != 'private' && document.type != 'internal'" +/// ```norust +/// title: "Public documents" +/// description: "Determine whether the document should be publicly visible" +/// expression: "document.type != 'private' && document.type != 'internal'" +/// ``` /// /// Example (Data Manipulation): /// -/// title: "Notification string" -/// description: "Create a notification string with a timestamp." -/// expression: "'New message received at ' + string(document.create_time)" +/// ```norust +/// title: "Notification string" +/// description: "Create a notification string with a timestamp." +/// expression: "'New message received at ' + string(document.create_time)" +/// ``` /// /// The exact variables and functions that may be referenced within an expression /// are determined by the service that evaluates it. See the service diff --git a/generator/testdata/rust/openapi/golden/src/model.rs b/generator/testdata/rust/openapi/golden/src/model.rs index 54163dbc..458eb2fd 100755 --- a/generator/testdata/rust/openapi/golden/src/model.rs +++ b/generator/testdata/rust/openapi/golden/src/model.rs @@ -60,7 +60,9 @@ pub struct Location { /// Cross-service attributes for the location. For example /// - /// {"cloud.googleapis.com/region": "us-east1"} + /// ```norust + /// {"cloud.googleapis.com/region": "us-east1"} + /// ``` #[serde(skip_serializing_if = "std::collections::HashMap::is_empty")] pub labels: std::collections::HashMap, @@ -888,9 +890,11 @@ impl ReplicaStatus { /// empty messages in your APIs. A typical example is to use it as the request /// or the response type of an API method. For instance: /// -/// service Foo { -/// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); -/// } +/// ```norust +/// service Foo { +/// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); +/// } +/// ``` #[serde_with::serde_as] #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default, rename_all = "camelCase")] @@ -1540,27 +1544,35 @@ impl Binding { /// /// Example (Comparison): /// -/// title: "Summary size limit" -/// description: "Determines if a summary is less than 100 chars" -/// expression: "document.summary.size() < 100" +/// ```norust +/// title: "Summary size limit" +/// description: "Determines if a summary is less than 100 chars" +/// expression: "document.summary.size() < 100" +/// ``` /// /// Example (Equality): /// -/// title: "Requestor is owner" -/// description: "Determines if requestor is the document owner" -/// expression: "document.owner == request.auth.claims.email" +/// ```norust +/// title: "Requestor is owner" +/// description: "Determines if requestor is the document owner" +/// expression: "document.owner == request.auth.claims.email" +/// ``` /// /// Example (Logic): /// -/// title: "Public documents" -/// description: "Determine whether the document should be publicly visible" -/// expression: "document.type != 'private' && document.type != 'internal'" +/// ```norust +/// title: "Public documents" +/// description: "Determine whether the document should be publicly visible" +/// expression: "document.type != 'private' && document.type != 'internal'" +/// ``` /// /// Example (Data Manipulation): /// -/// title: "Notification string" -/// description: "Create a notification string with a timestamp." -/// expression: "'New message received at ' + string(document.create_time)" +/// ```norust +/// title: "Notification string" +/// description: "Create a notification string with a timestamp." +/// expression: "'New message received at ' + string(document.create_time)" +/// ``` /// /// The exact variables and functions that may be referenced within an expression /// are determined by the service that evaluates it. See the service @@ -1626,41 +1638,43 @@ impl Expr { /// /// Example Policy with multiple AuditConfigs: /// +/// ```norust +/// { +/// "audit_configs": [ /// { -/// "audit_configs": [ +/// "service": "allServices", +/// "audit_log_configs": [ /// { -/// "service": "allServices", -/// "audit_log_configs": [ -/// { -/// "log_type": "DATA_READ", -/// "exempted_members": [ -/// "user:jose@example.com" -/// ] -/// }, -/// { -/// "log_type": "DATA_WRITE" -/// }, -/// { -/// "log_type": "ADMIN_READ" -/// } +/// "log_type": "DATA_READ", +/// "exempted_members": [ +/// "user:jose@example.com" /// ] /// }, /// { -/// "service": "sampleservice.googleapis.com", -/// "audit_log_configs": [ -/// { -/// "log_type": "DATA_READ" -/// }, -/// { -/// "log_type": "DATA_WRITE", -/// "exempted_members": [ -/// "user:aliya@example.com" -/// ] -/// } +/// "log_type": "DATA_WRITE" +/// }, +/// { +/// "log_type": "ADMIN_READ" +/// } +/// ] +/// }, +/// { +/// "service": "sampleservice.googleapis.com", +/// "audit_log_configs": [ +/// { +/// "log_type": "DATA_READ" +/// }, +/// { +/// "log_type": "DATA_WRITE", +/// "exempted_members": [ +/// "user:aliya@example.com" /// ] /// } /// ] /// } +/// ] +/// } +/// ``` /// /// For sampleservice, this policy enables DATA_READ, DATA_WRITE and ADMIN_READ /// logging. It also exempts `jose@example.com` from DATA_READ logging, and @@ -1699,19 +1713,21 @@ impl AuditConfig { /// Provides the configuration for logging a type of permissions. /// Example: /// +/// ```norust +/// { +/// "audit_log_configs": [ /// { -/// "audit_log_configs": [ -/// { -/// "log_type": "DATA_READ", -/// "exempted_members": [ -/// "user:jose@example.com" -/// ] -/// }, -/// { -/// "log_type": "DATA_WRITE" -/// } +/// "log_type": "DATA_READ", +/// "exempted_members": [ +/// "user:jose@example.com" /// ] +/// }, +/// { +/// "log_type": "DATA_WRITE" /// } +/// ] +/// } +/// ``` /// /// This enables 'DATA_READ' and 'DATA_WRITE' logging, while exempting /// jose@example.com from DATA_READ logging. diff --git a/src/gax/src/error/rpc/generated/mod.rs b/src/gax/src/error/rpc/generated/mod.rs index df9ba599..3a2459f7 100644 --- a/src/gax/src/error/rpc/generated/mod.rs +++ b/src/gax/src/error/rpc/generated/mod.rs @@ -19,25 +19,29 @@ /// Example of an error when contacting the "pubsub.googleapis.com" API when it /// is not enabled: /// -/// { "reason": "API_DISABLED" -/// "domain": "googleapis.com" -/// "metadata": { -/// "resource": "projects/123", -/// "service": "pubsub.googleapis.com" -/// } -/// } +/// ```norust +/// { "reason": "API_DISABLED" +/// "domain": "googleapis.com" +/// "metadata": { +/// "resource": "projects/123", +/// "service": "pubsub.googleapis.com" +/// } +/// } +/// ``` /// /// This response indicates that the pubsub.googleapis.com API is not enabled. /// /// Example of an error that is returned when attempting to create a Spanner /// instance in a region that is out of stock: /// -/// { "reason": "STOCKOUT" -/// "domain": "spanner.googleapis.com", -/// "metadata": { -/// "availableRegions": "us-central1,us-east2" -/// } -/// } +/// ```norust +/// { "reason": "STOCKOUT" +/// "domain": "spanner.googleapis.com", +/// "metadata": { +/// "availableRegions": "us-central1,us-east2" +/// } +/// } +/// ``` #[serde_with::serde_as] #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] @@ -335,21 +339,27 @@ pub mod bad_request { /// /// Consider the following: /// - /// message CreateContactRequest { - /// message EmailAddress { - /// enum Type { - /// TYPE_UNSPECIFIED = 0; - /// HOME = 1; - /// WORK = 2; - /// } + /// ```norust + /// message CreateContactRequest { + /// message EmailAddress { + /// enum Type { + /// TYPE_UNSPECIFIED = 0; + /// HOME = 1; + /// WORK = 2; + /// } + /// ``` /// - /// optional string email = 1; - /// repeated EmailType type = 2; - /// } + /// ```norust + /// optional string email = 1; + /// repeated EmailType type = 2; + /// } + /// ``` /// - /// string full_name = 1; - /// repeated EmailAddress email_addresses = 2; - /// } + /// ```norust + /// string full_name = 1; + /// repeated EmailAddress email_addresses = 2; + /// } + /// ``` /// /// In this example, in proto `field` could take one of the following values: /// diff --git a/src/generated/cloud/location/src/model.rs b/src/generated/cloud/location/src/model.rs index f5a776bf..331f42d5 100755 --- a/src/generated/cloud/location/src/model.rs +++ b/src/generated/cloud/location/src/model.rs @@ -123,7 +123,9 @@ pub struct Location { /// Cross-service attributes for the location. For example /// - /// {"cloud.googleapis.com/region": "us-east1"} + /// ```norust + /// {"cloud.googleapis.com/region": "us-east1"} + /// ``` #[serde(skip_serializing_if = "std::collections::HashMap::is_empty")] pub labels: std::collections::HashMap, diff --git a/src/generated/iam/v1/src/model.rs b/src/generated/iam/v1/src/model.rs index 86447a93..2cf44cf5 100755 --- a/src/generated/iam/v1/src/model.rs +++ b/src/generated/iam/v1/src/model.rs @@ -437,41 +437,43 @@ impl Binding { /// /// Example Policy with multiple AuditConfigs: /// +/// ```norust +/// { +/// "audit_configs": [ /// { -/// "audit_configs": [ +/// "service": "allServices", +/// "audit_log_configs": [ /// { -/// "service": "allServices", -/// "audit_log_configs": [ -/// { -/// "log_type": "DATA_READ", -/// "exempted_members": [ -/// "user:jose@example.com" -/// ] -/// }, -/// { -/// "log_type": "DATA_WRITE" -/// }, -/// { -/// "log_type": "ADMIN_READ" -/// } +/// "log_type": "DATA_READ", +/// "exempted_members": [ +/// "user:jose@example.com" /// ] /// }, /// { -/// "service": "sampleservice.googleapis.com", -/// "audit_log_configs": [ -/// { -/// "log_type": "DATA_READ" -/// }, -/// { -/// "log_type": "DATA_WRITE", -/// "exempted_members": [ -/// "user:aliya@example.com" -/// ] -/// } +/// "log_type": "DATA_WRITE" +/// }, +/// { +/// "log_type": "ADMIN_READ" +/// } +/// ] +/// }, +/// { +/// "service": "sampleservice.googleapis.com", +/// "audit_log_configs": [ +/// { +/// "log_type": "DATA_READ" +/// }, +/// { +/// "log_type": "DATA_WRITE", +/// "exempted_members": [ +/// "user:aliya@example.com" /// ] /// } /// ] /// } +/// ] +/// } +/// ``` /// /// For sampleservice, this policy enables DATA_READ, DATA_WRITE and ADMIN_READ /// logging. It also exempts `jose@example.com` from DATA_READ logging, and @@ -510,19 +512,21 @@ impl AuditConfig { /// Provides the configuration for logging a type of permissions. /// Example: /// +/// ```norust +/// { +/// "audit_log_configs": [ /// { -/// "audit_log_configs": [ -/// { -/// "log_type": "DATA_READ", -/// "exempted_members": [ -/// "user:jose@example.com" -/// ] -/// }, -/// { -/// "log_type": "DATA_WRITE" -/// } +/// "log_type": "DATA_READ", +/// "exempted_members": [ +/// "user:jose@example.com" /// ] +/// }, +/// { +/// "log_type": "DATA_WRITE" /// } +/// ] +/// } +/// ``` /// /// This enables 'DATA_READ' and 'DATA_WRITE' logging, while exempting /// jose@example.com from DATA_READ logging. diff --git a/src/generated/type/src/model.rs b/src/generated/type/src/model.rs index 273b7f1f..0c0e92aa 100755 --- a/src/generated/type/src/model.rs +++ b/src/generated/type/src/model.rs @@ -34,110 +34,134 @@ /// /// Example (Java): /// -/// import com.google.type.Color; +/// ```norust +/// import com.google.type.Color; +/// ``` /// -/// // ... -/// public static java.awt.Color fromProto(Color protocolor) { -/// float alpha = protocolor.hasAlpha() -/// ? protocolor.getAlpha().getValue() -/// : 1.0; +/// ```norust +/// // ... +/// public static java.awt.Color fromProto(Color protocolor) { +/// float alpha = protocolor.hasAlpha() +/// ? protocolor.getAlpha().getValue() +/// : 1.0; +/// ``` /// -/// return new java.awt.Color( -/// protocolor.getRed(), -/// protocolor.getGreen(), -/// protocolor.getBlue(), -/// alpha); -/// } +/// ```norust +/// return new java.awt.Color( +/// protocolor.getRed(), +/// protocolor.getGreen(), +/// protocolor.getBlue(), +/// alpha); +/// } +/// ``` /// -/// public static Color toProto(java.awt.Color color) { -/// float red = (float) color.getRed(); -/// float green = (float) color.getGreen(); -/// float blue = (float) color.getBlue(); -/// float denominator = 255.0; -/// Color.Builder resultBuilder = -/// Color -/// .newBuilder() -/// .setRed(red / denominator) -/// .setGreen(green / denominator) -/// .setBlue(blue / denominator); -/// int alpha = color.getAlpha(); -/// if (alpha != 255) { -/// result.setAlpha( -/// FloatValue -/// .newBuilder() -/// .setValue(((float) alpha) / denominator) -/// .build()); -/// } -/// return resultBuilder.build(); -/// } -/// // ... +/// ```norust +/// public static Color toProto(java.awt.Color color) { +/// float red = (float) color.getRed(); +/// float green = (float) color.getGreen(); +/// float blue = (float) color.getBlue(); +/// float denominator = 255.0; +/// Color.Builder resultBuilder = +/// Color +/// .newBuilder() +/// .setRed(red / denominator) +/// .setGreen(green / denominator) +/// .setBlue(blue / denominator); +/// int alpha = color.getAlpha(); +/// if (alpha != 255) { +/// result.setAlpha( +/// FloatValue +/// .newBuilder() +/// .setValue(((float) alpha) / denominator) +/// .build()); +/// } +/// return resultBuilder.build(); +/// } +/// // ... +/// ``` /// /// Example (iOS / Obj-C): /// -/// // ... -/// static UIColor* fromProto(Color* protocolor) { -/// float red = [protocolor red]; -/// float green = [protocolor green]; -/// float blue = [protocolor blue]; -/// FloatValue* alpha_wrapper = [protocolor alpha]; -/// float alpha = 1.0; -/// if (alpha_wrapper != nil) { -/// alpha = [alpha_wrapper value]; -/// } -/// return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; -/// } -/// -/// static Color* toProto(UIColor* color) { -/// CGFloat red, green, blue, alpha; -/// if (![color getRed:&red green:&green blue:&blue alpha:&alpha]) { -/// return nil; -/// } -/// Color* result = [[Color alloc] init]; -/// [result setRed:red]; -/// [result setGreen:green]; -/// [result setBlue:blue]; -/// if (alpha <= 0.9999) { -/// [result setAlpha:floatWrapperWithValue(alpha)]; -/// } -/// [result autorelease]; -/// return result; +/// ```norust +/// // ... +/// static UIColor* fromProto(Color* protocolor) { +/// float red = [protocolor red]; +/// float green = [protocolor green]; +/// float blue = [protocolor blue]; +/// FloatValue* alpha_wrapper = [protocolor alpha]; +/// float alpha = 1.0; +/// if (alpha_wrapper != nil) { +/// alpha = [alpha_wrapper value]; /// } -/// // ... +/// return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; +/// } +/// ``` +/// +/// ```norust +/// static Color* toProto(UIColor* color) { +/// CGFloat red, green, blue, alpha; +/// if (![color getRed:&red green:&green blue:&blue alpha:&alpha]) { +/// return nil; +/// } +/// Color* result = [[Color alloc] init]; +/// [result setRed:red]; +/// [result setGreen:green]; +/// [result setBlue:blue]; +/// if (alpha <= 0.9999) { +/// [result setAlpha:floatWrapperWithValue(alpha)]; +/// } +/// [result autorelease]; +/// return result; +/// } +/// // ... +/// ``` /// /// Example (JavaScript): /// -/// // ... +/// ```norust +/// // ... +/// ``` /// -/// var protoToCssColor = function(rgb_color) { -/// var redFrac = rgb_color.red || 0.0; -/// var greenFrac = rgb_color.green || 0.0; -/// var blueFrac = rgb_color.blue || 0.0; -/// var red = Math.floor(redFrac * 255); -/// var green = Math.floor(greenFrac * 255); -/// var blue = Math.floor(blueFrac * 255); +/// ```norust +/// var protoToCssColor = function(rgb_color) { +/// var redFrac = rgb_color.red || 0.0; +/// var greenFrac = rgb_color.green || 0.0; +/// var blueFrac = rgb_color.blue || 0.0; +/// var red = Math.floor(redFrac * 255); +/// var green = Math.floor(greenFrac * 255); +/// var blue = Math.floor(blueFrac * 255); +/// ``` /// -/// if (!('alpha' in rgb_color)) { -/// return rgbToCssColor(red, green, blue); -/// } +/// ```norust +/// if (!('alpha' in rgb_color)) { +/// return rgbToCssColor(red, green, blue); +/// } +/// ``` /// -/// var alphaFrac = rgb_color.alpha.value || 0.0; -/// var rgbParams = [red, green, blue].join(','); -/// return ['rgba(', rgbParams, ',', alphaFrac, ')'].join(''); -/// }; +/// ```norust +/// var alphaFrac = rgb_color.alpha.value || 0.0; +/// var rgbParams = [red, green, blue].join(','); +/// return ['rgba(', rgbParams, ',', alphaFrac, ')'].join(''); +/// }; +/// ``` /// -/// var rgbToCssColor = function(red, green, blue) { -/// var rgbNumber = new Number((red << 16) | (green << 8) | blue); -/// var hexString = rgbNumber.toString(16); -/// var missingZeros = 6 - hexString.length; -/// var resultBuilder = ['#']; -/// for (var i = 0; i < missingZeros; i++) { -/// resultBuilder.push('0'); -/// } -/// resultBuilder.push(hexString); -/// return resultBuilder.join(''); -/// }; +/// ```norust +/// var rgbToCssColor = function(red, green, blue) { +/// var rgbNumber = new Number((red << 16) | (green << 8) | blue); +/// var hexString = rgbNumber.toString(16); +/// var missingZeros = 6 - hexString.length; +/// var resultBuilder = ['#']; +/// for (var i = 0; i < missingZeros; i++) { +/// resultBuilder.push('0'); +/// } +/// resultBuilder.push(hexString); +/// return resultBuilder.join(''); +/// }; +/// ``` /// -/// // ... +/// ```norust +/// // ... +/// ``` #[serde_with::serde_as] #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default, rename_all = "camelCase")] @@ -458,17 +482,27 @@ pub struct Decimal { /// /// The ENBF grammar is: /// - /// DecimalString = - /// [Sign] Significand [Exponent]; + /// ```norust + /// DecimalString = + /// [Sign] Significand [Exponent]; + /// ``` /// - /// Sign = '+' | '-'; + /// ```norust + /// Sign = '+' | '-'; + /// ``` /// - /// Significand = - /// Digits ['.'] [Digits] | [Digits] '.' Digits; + /// ```norust + /// Significand = + /// Digits ['.'] [Digits] | [Digits] '.' Digits; + /// ``` /// - /// Exponent = ('e' | 'E') [Sign] Digits; + /// ```norust + /// Exponent = ('e' | 'E') [Sign] Digits; + /// ``` /// - /// Digits = { '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' }; + /// ```norust + /// Digits = { '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' }; + /// ``` /// /// Services **should** clearly document the range of supported values, the /// maximum supported precision (total number of digits), and, if applicable, @@ -500,27 +534,35 @@ impl Decimal { /// /// Example (Comparison): /// -/// title: "Summary size limit" -/// description: "Determines if a summary is less than 100 chars" -/// expression: "document.summary.size() < 100" +/// ```norust +/// title: "Summary size limit" +/// description: "Determines if a summary is less than 100 chars" +/// expression: "document.summary.size() < 100" +/// ``` /// /// Example (Equality): /// -/// title: "Requestor is owner" -/// description: "Determines if requestor is the document owner" -/// expression: "document.owner == request.auth.claims.email" +/// ```norust +/// title: "Requestor is owner" +/// description: "Determines if requestor is the document owner" +/// expression: "document.owner == request.auth.claims.email" +/// ``` /// /// Example (Logic): /// -/// title: "Public documents" -/// description: "Determine whether the document should be publicly visible" -/// expression: "document.type != 'private' && document.type != 'internal'" +/// ```norust +/// title: "Public documents" +/// description: "Determine whether the document should be publicly visible" +/// expression: "document.type != 'private' && document.type != 'internal'" +/// ``` /// /// Example (Data Manipulation): /// -/// title: "Notification string" -/// description: "Create a notification string with a timestamp." -/// expression: "'New message received at ' + string(document.create_time)" +/// ```norust +/// title: "Notification string" +/// description: "Create a notification string with a timestamp." +/// expression: "'New message received at ' + string(document.create_time)" +/// ``` /// /// The exact variables and functions that may be referenced within an expression /// are determined by the service that evaluates it. See the service @@ -763,11 +805,17 @@ impl Money { /// For instance, in Java this would be: /// /// com.google.type.PhoneNumber wireProto = -/// com.google.type.PhoneNumber.newBuilder().build(); +/// ```norust +/// com.google.type.PhoneNumber.newBuilder().build(); +/// ``` /// com.google.i18n.phonenumbers.Phonenumber.PhoneNumber phoneNumber = -/// PhoneNumberUtil.getInstance().parse(wireProto.getE164Number(), "ZZ"); +/// ```norust +/// PhoneNumberUtil.getInstance().parse(wireProto.getE164Number(), "ZZ"); +/// ``` /// if (!wireProto.getExtension().isEmpty()) { -/// phoneNumber.setExtension(wireProto.getExtension()); +/// ```norust +/// phoneNumber.setExtension(wireProto.getExtension()); +/// ``` /// } /// /// Reference(s): @@ -1077,7 +1125,9 @@ impl PostalAddress { /// /// Quaternions are generally represented in this form: /// -/// w + xi + yj + zk +/// ```norust +/// w + xi + yj + zk +/// ``` /// /// where x, y, z, and w are real numbers, and i, j, and k are three imaginary /// numbers. @@ -1093,10 +1143,12 @@ impl PostalAddress { /// buffer below *must* follow the Hamilton convention, which defines `ij = k` /// (i.e. a right-handed algebra), and therefore: /// -/// i^2 = j^2 = k^2 = ijk = −1 -/// ij = −ji = k -/// jk = −kj = i -/// ki = −ik = j +/// ```norust +/// i^2 = j^2 = k^2 = ijk = −1 +/// ij = −ji = k +/// jk = −kj = i +/// ki = −ik = j +/// ``` /// /// Please DO NOT use this to represent quaternions that follow the JPL /// convention, or any of the other quaternion flavors out there.