Skip to content
Open
Show file tree
Hide file tree
Changes from 8 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 c/cbindgen.toml
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,5 @@ FoxgloveLogLevel = "foxglove_log_level"
FoxgloveSceneEntityDeletionType = "foxglove_scene_entity_deletion_type"
FoxgloveNumericType = "foxglove_numeric_type"
FoxglovePointsAnnotationType = "foxglove_points_annotation_type"
FoxglovePointStyle = "foxglove_point_style"
FoxglovePositionCovarianceType = "foxglove_position_covariance_type"
20 changes: 20 additions & 0 deletions c/include/foxglove-c/foxglove-c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions c/src/generated_types.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions cpp/foxglove/include/foxglove/schemas.hpp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions cpp/foxglove/src/schemas.cpp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions python/foxglove-sdk/python/foxglove/_foxglove_py/schemas.pyi

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions python/foxglove-sdk/python/foxglove/schemas/__init__.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 19 additions & 2 deletions python/foxglove-sdk/src/generated/schemas.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions ros/src/foxglove_msgs/ros1/LocationFix.msg

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions ros/src/foxglove_msgs/ros2/LocationFix.msg

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

94 changes: 94 additions & 0 deletions rust/foxglove/src/schemas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,58 @@ macro_rules! serde_enum_mod {
#[cfg(feature = "serde")]
pub(crate) use serde_enum_mod;

/// Generates a serde module for an optional protobuf enum field.
///
/// Uses string names for human-readable formats (JSON) and i32 for binary formats.
#[cfg(feature = "serde")]
macro_rules! serde_enum_mod_optional {
Copy link
Member

Choose a reason for hiding this comment

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

@eloff @ericmlujan could you folks review this part? I'm not familiar with this code at all and @gasmith is out -- I do wonder if there's a way we could combine this with the non-optional macro rather than having two whole macros for it? but not sure how feasible that suggestion is

Copy link
Author

Choose a reason for hiding this comment

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

I'm certainly not confident enough in Rust macros to combine them nicely, especially for SDK level code. This was done because it was easier for me to understand and easier for me to read.

Super happy to change this if someone better at rust has some ideas.

($mod_name:ident, $enum_path:ty) => {
pub mod $mod_name {
use super::*;

pub fn serialize<S>(v: &Option<i32>, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match v {
Some(v) => {
if s.is_human_readable() {
let e = <$enum_path>::try_from(*v)
.map_err(|_| serde::ser::Error::custom("invalid enum value"))?;
s.serialize_some(e.as_str_name())
} else {
s.serialize_some(v)
}
}
None => s.serialize_none(),
}
}

pub fn deserialize<'de, D>(d: D) -> Result<Option<i32>, D::Error>
where
D: Deserializer<'de>,
{
if d.is_human_readable() {
let opt: Option<String> = Option::deserialize(d)?;
match opt {
Some(s) => {
let e = <$enum_path>::from_str_name(&s)
.ok_or_else(|| D::Error::custom("invalid enum string"))?;
Ok(Some(e as i32))
}
None => Ok(None),
}
} else {
Option::<i32>::deserialize(d)
}
}
}
};
}

#[cfg(feature = "serde")]
pub(crate) use serde_enum_mod_optional;

#[cfg(test)]
#[cfg(feature = "serde")]
mod tests {
Expand Down Expand Up @@ -200,4 +252,46 @@ mod tests {
let parsed: Grid = serde_cbor::from_slice(&bytes).expect("failed to deserialize");
assert_eq!(grid, parsed);
}

#[test]
fn test_location_fix_json_roundtrip_with_point_style() {
use super::{location_fix::PointStyle, LocationFix};

let fix = LocationFix {
latitude: 37.7749,
longitude: -122.4194,
altitude: 10.0,
point_style: Some(PointStyle::Pin as i32),
..Default::default()
};
let json = serde_json::to_string(&fix).expect("failed to serialize");
assert!(json.contains("\"point_style\":\"PIN\""));
let parsed: LocationFix = serde_json::from_str(&json).expect("failed to deserialize");
assert_eq!(fix, parsed);
}

#[test]
fn test_location_fix_json_roundtrip_with_none_point_style() {
use super::LocationFix;

let fix = LocationFix {
latitude: 37.7749,
longitude: -122.4194,
point_style: None,
..Default::default()
};
let json = serde_json::to_string(&fix).expect("failed to serialize");
assert!(json.contains("\"point_style\":null"));
let parsed: LocationFix = serde_json::from_str(&json).expect("failed to deserialize");
assert_eq!(fix, parsed);
}

#[test]
fn test_location_fix_json_invalid_point_style() {
use super::LocationFix;

let json = r#"{"point_style":"INVALID_VALUE","latitude":0.0,"longitude":0.0,"altitude":0.0,"position_covariance":[],"position_covariance_type":"UNKNOWN"}"#;
let result: Result<LocationFix, _> = serde_json::from_str(json);
assert!(result.is_err());
}
}
Binary file modified rust/foxglove/src/schemas/data/LocationFix.bin
Binary file not shown.
Binary file modified rust/foxglove/src/schemas/data/LocationFixes.bin
Binary file not shown.
Loading
Loading