feat(opcua): capture node DataType during browse and metadata reads - #497
feat(opcua): capture node DataType during browse and metadata reads#497cartercanedy wants to merge 3 commits into
Conversation
Co-Authored-By: Carter Canedy <carter.canedy@nominal.io>
|
Claude finished @cartercanedy's task in 2m 30s —— View job Review: capture Variable node DataType during browse
Overview Clean, well-scoped change. Batching the One thing worth a decision before merge: adding Two inline notes posted on the diff:
No missing-driver-convention, docstring, or docs-sync issues — this is a crate-internal Rust struct, not exposed via PyO3. |
| /// The `DataType` attribute of a `Variable` node; `None` for other node classes or when unknown. | ||
| #[serde(default, skip_serializing_if = "Option::is_none")] | ||
| pub data_type: Option<OpcUaNodeId>, |
There was a problem hiding this comment.
Adding data_type to the public OpcUaNode struct breaks downstream code that constructs this published 1.x type with struct literals: those consumers will no longer compile until they add the field. Because this is recorded as a regular feature, the next release can present the change as semver-compatible. Mark and release it as a breaking change, or provide a forward-compatible construction path.
Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/instro-opcua/src/types.rs
Line: 857-859
Comment:
**Public field breaks consumers**
Adding `data_type` to the public `OpcUaNode` struct breaks downstream code that constructs this published 1.x type with struct literals: those consumers will no longer compile until they add the field. Because this is recorded as a regular feature, the next release can present the change as semver-compatible. Mark and release it as a breaking change, or provide a forward-compatible construction path.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Agreed it's source-breaking for struct-literal consumers (connect's are updated in nominal-io/connect#3637, which pins this commit). Leaving the feat vs feat! call to @cartercanedy — happy to retitle if you want it released as a major.
There was a problem hiding this comment.
Thanks for confirming. The companion PR addresses the known consumer, but the public-field addition remains source-breaking for other downstream struct-literal users. I recommend treating this as feat! and releasing it as a major version if this crate follows semver; otherwise, make the breaking change explicit in the release notes. No further code change is needed for this comment.
Tip: You can customize Greptile's behavior for this repo with .greptile/rules.md and .greptile/config.json.
…t mismatch Co-Authored-By: Carter Canedy <carter.canedy@nominal.io>
…er browse Co-Authored-By: Carter Canedy <carter.canedy@nominal.io>
Summary
OpcUaNodegainsdata_type: Option<OpcUaNodeId>(#[serde(default, skip_serializing_if = "Option::is_none")], so existing serialized trees still deserialize and non-variables don't emit the key).OpcUaNode::data_type_name() -> Option<Cow<'static, str>>maps ns=0 builtin type ids (i=1..=29:Boolean,Int32,Double,String, …) to their names and falls back to the canonical node id string for custom types.Browse for OpcUaClient::browse_nodenow issues one batchedread_many_attributes(DATATYPE)for theVariablechildren of each browsed node (one extra request per browse level, zero when a level has no variables). A failed read is logged and leavesdata_type = Nonerather than failing the browse.Type of change
feat)Verification
cargo check/clippy -p instro-opcua --all-targets --all-features,cargo +nightly fmt --check,cargo test -p instro-opcua: 73 unit + 6client_harnesstests pass. Not exercised against a real server beyond the harness.Tests
data_type; newdata_type_name_maps_builtin_and_falls_back_to_node_id.Checklist
Notes for reviewers
Adding a public struct field is technically a breaking change for downstream struct literals