Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- Rust and Rust Sym: Preserve object metric property names containing dots, hyphens, or uppercase letters when serializing and deserializing JSON ([bug 1929903](https://bugzilla.mozilla.org/show_bug.cgi?id=1929903)).
- Support `flows.yaml` files (`moz://mozilla.org/schemas/glean/flows/1-0-0`), declaring multi-step tasks measured as a unit over existing event metrics. Flows are validated against the metrics passed to the parser, with warnings for events that aren't defined in any of them (`UNRESOLVED_FLOW_EVENT`) and for flows with no exit events (`EMPTY_ENDS_ON`). Kotlin, Swift, and Rust output gains the flow definitions to pass to Glean at initialization (`GleanFlows`), and Markdown output documents flows and the flows each event belongs to. Flows are passed to external translators as the `flows` option ([bug 2077133](https://bugzilla.mozilla.org/show_bug.cgi?id=2077133))
- Fix tests that failed when `SOURCE_DATE_EPOCH` is set in the environment
- Add a `skip_schema_validation` option to `parse_objects` to skip schema validation of input files ([bug 2076540](https://bugzilla.mozilla.org/show_bug.cgi?id=2076540))
Expand Down
1 change: 1 addition & 0 deletions glean_parser/templates/rust.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Jinja2 template is not. Please file bugs! #}
#[serde(deny_unknown_fields)]
pub struct {{ name }} {
{% for itemname, val in struct.properties.items() %}
#[serde(rename = "{{ itemname }}")]
{% if val.type == "array" %}
#[serde(skip_serializing_if = "Vec::is_empty", default = "Vec::new", deserialize_with = "::glean::traits::__serde_helper::vec_null")]
pub {{itemname|snake_case}}: {{ name ~ itemname|Camelize }},
Expand Down
1 change: 1 addition & 0 deletions glean_parser/templates/rust_sym.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Jinja2 template is not. Please file bugs! #}
#[serde(deny_unknown_fields)]
pub struct {{ name }} {
{% for itemname, val in struct.properties.items() %}
#[serde(rename = "{{ itemname }}")]
{% if val.type == "array" %}
#[serde(skip_serializing_if = "Vec::is_empty", default = "Vec::new", deserialize_with = "::glean_sym::__serde_helper::vec_null")]
pub {{itemname|snake_case}}: {{ name ~ itemname|Camelize }},
Expand Down
14 changes: 7 additions & 7 deletions tests/data/object.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ complex.types:
structure:
type: object
properties:
key1:
foo.bar-baz:
type: string
another_value:
CamelCase:
type: number
sub_array:
sub-array:
type: array
items:
type: number
Expand All @@ -79,7 +79,7 @@ complex.types:
properties:
key:
type: string
value:
choice-value:
oneOf:
- type: string
- type: number
Expand All @@ -91,7 +91,7 @@ activity.stream:
type: object
description: |
The id, position, and shim for each newtab tile and any extra nested data,
e.g. `[{"id": 1, "pos": 2, "shim": "long-id", "nested": { "count": 17, "info": "more info"}}]`
e.g. `[{"id": 1, "pos": 2, "shim": "long-id", "nested-object": { "count": 17, "nested.info": "more info"}}]`
bugs:
- https://bugzilla.mozilla.org/11137353
data_reviews:
Expand All @@ -110,12 +110,12 @@ activity.stream:
type: number
shim:
type: string
nested:
nested-object:
type: object
properties:
count:
type: number
info:
nested.info:
type: string

crash.stack:
Expand Down
26 changes: 21 additions & 5 deletions tests/test_rust.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import subprocess
import re

import pytest

from glean_parser import rust
from glean_parser import metrics
from glean_parser import pings
Expand Down Expand Up @@ -257,13 +259,12 @@ def test_event_extra_keys_with_types(tmp_path):
)


def test_object_metric(tmp_path):
"""
Assert that an object metric is created.
"""
@pytest.mark.parametrize("output_format", ["rust", "rust_sym"])
def test_object_metric(tmp_path, output_format):
"""Assert that object metrics preserve their property names in JSON."""
translate.translate(
ROOT / "data" / "object.yaml",
"rust",
output_format,
tmp_path,
{"namespace": "Foo"},
)
Expand All @@ -288,6 +289,21 @@ def test_object_metric(tmp_path):
assert "trust: Option<String>, " in content
assert "}" in content

for original, field in [
("foo.bar-baz", "foo_bar_baz"),
("CamelCase", "camelcase"),
("sub-array", "sub_array"),
("nested-object", "nested_object"),
("nested.info", "nested_info"),
("choice-value", "choice_value"),
("module_index", "module_index"),
]:
assert re.search(
rf'#\[serde\(rename = "{re.escape(original)}"\)\] '
+ rf"#\[serde\([^\]]*\)\] pub {field}:",
content,
)


def test_in_session_output(tmp_path):
"""Assert that in_session: true produces in_session: true in Rust output."""
Expand Down
Loading