diff --git a/Cargo.lock b/Cargo.lock index 2af0cf29..e647b96b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,9 +60,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "arc-swap" @@ -70,15 +70,292 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +[[package]] +name = "async-opcua" +version = "0.13.0" +dependencies = [ + "async-opcua", + "async-opcua-client", + "async-opcua-core", + "async-opcua-core-namespace", + "async-opcua-crypto", + "async-opcua-macros", + "async-opcua-nodes", + "async-opcua-server", + "async-opcua-types", + "async-trait", + "bytes", + "chrono", + "env_logger", + "log", + "serde_json", + "tempdir", + "tokio", + "tokio-util", +] + +[[package]] +name = "async-opcua-certificate-creator" +version = "0.13.0" +dependencies = [ + "async-opcua", + "pico-args", +] + +[[package]] +name = "async-opcua-chess-server" +version = "0.13.0" +dependencies = [ + "async-opcua", + "tokio", + "uci", +] + +[[package]] +name = "async-opcua-client" +version = "0.13.0" +dependencies = [ + "arc-swap", + "async-opcua-core", + "async-opcua-crypto", + "async-opcua-nodes", + "async-opcua-types", + "async-opcua-xml", + "async-trait", + "chrono", + "futures", + "hashbrown 0.15.2", + "log", + "parking_lot", + "rsa", + "serde", + "tokio", + "tokio-util", +] + +[[package]] +name = "async-opcua-codegen" +version = "0.1.0" +dependencies = [ + "async-opcua-xml", + "base64 0.22.1", + "chrono", + "convert_case", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "roxmltree", + "serde", + "serde_json", + "serde_yaml", + "syn 2.0.96", + "thiserror", + "uuid", +] + +[[package]] +name = "async-opcua-core" +version = "0.13.0" +dependencies = [ + "async-opcua-crypto", + "async-opcua-types", + "bytes", + "chrono", + "log", + "parking_lot", + "serde", + "serde_yaml", + "thiserror", + "tokio", + "tokio-util", + "url", +] + +[[package]] +name = "async-opcua-core-namespace" +version = "0.13.0" +dependencies = [ + "async-opcua-nodes", + "async-opcua-types", +] + +[[package]] +name = "async-opcua-crypto" +version = "0.13.0" +dependencies = [ + "aes", + "async-opcua-types", + "cbc", + "chrono", + "const-oid", + "gethostname", + "hmac", + "log", + "rand 0.8.5", + "rsa", + "serde", + "sha1", + "sha2", + "tempdir", + "x509-cert", +] + +[[package]] +name = "async-opcua-demo-server" +version = "0.13.0" +dependencies = [ + "async-opcua", + "chrono", + "log", + "log4rs", + "pico-args", + "rand 0.8.5", + "tokio", + "tokio-util", +] + +[[package]] +name = "async-opcua-discovery-client" +version = "0.13.0" +dependencies = [ + "async-opcua", + "pico-args", + "tokio", +] + +[[package]] +name = "async-opcua-event-client" +version = "0.13.0" +dependencies = [ + "async-opcua", + "pico-args", + "tokio", +] + +[[package]] +name = "async-opcua-macros" +version = "0.1.0" +dependencies = [ + "base64 0.22.1", + "convert_case", + "proc-macro2", + "quote", + "syn 2.0.96", + "uuid", +] + +[[package]] +name = "async-opcua-mqtt-client" +version = "0.13.0" +dependencies = [ + "async-opcua", + "pico-args", + "rumqttc", + "tokio", +] + +[[package]] +name = "async-opcua-nodes" +version = "0.13.0" +dependencies = [ + "async-opcua-macros", + "async-opcua-nodes", + "async-opcua-types", + "async-opcua-xml", + "bitflags", + "hashbrown 0.15.2", + "log", + "regex", + "thiserror", +] + +[[package]] +name = "async-opcua-server" +version = "0.13.0" +dependencies = [ + "arc-swap", + "async-opcua-client", + "async-opcua-core", + "async-opcua-core-namespace", + "async-opcua-crypto", + "async-opcua-nodes", + "async-opcua-types", + "async-trait", + "bitflags", + "chrono", + "futures", + "hashbrown 0.15.2", + "log", + "parking_lot", + "postcard", + "regex", + "serde", + "serde_json", + "tokio", + "tokio-util", +] + +[[package]] +name = "async-opcua-simple-client" +version = "0.0.0" +dependencies = [ + "async-opcua", + "log", + "pico-args", + "tokio", +] + +[[package]] +name = "async-opcua-simple-server" +version = "0.13.0" +dependencies = [ + "async-opcua", + "chrono", + "log", + "tokio", +] + +[[package]] +name = "async-opcua-types" +version = "0.13.0" +dependencies = [ + "async-opcua-macros", + "async-opcua-types", + "async-opcua-xml", + "base64 0.22.1", + "bitflags", + "byteorder", + "chrono", + "hashbrown 0.15.2", + "log", + "regex", + "serde_json", + "struson", + "thiserror", + "uuid", +] + +[[package]] +name = "async-opcua-xml" +version = "0.1.0" +dependencies = [ + "chrono", + "roxmltree", + "thiserror", + "uuid", +] + [[package]] name = "async-trait" -version = "0.1.83" +version = "0.1.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -131,9 +408,9 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be" [[package]] name = "block-buffer" @@ -182,9 +459,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.4" +version = "1.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf" +checksum = "ad0cf6e91fde44c773c6ee7ec6bba798504641a8bc2eb7e37a04ffbf4dfaa55a" dependencies = [ "shlex", ] @@ -286,8 +563,8 @@ dependencies = [ name = "custom-codegen" version = "0.1.0" dependencies = [ + "async-opcua", "log", - "opcua", "serde", "serde_json", "serde_with", @@ -315,7 +592,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -326,7 +603,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -350,7 +627,7 @@ checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -400,7 +677,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -445,6 +722,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "erased-serde" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" +dependencies = [ + "serde", + "typeid", +] + [[package]] name = "errno" version = "0.3.10" @@ -459,9 +746,9 @@ dependencies = [ name = "external-tests" version = "0.1.0" dependencies = [ + "async-opcua", "futures", "log", - "opcua", "serde", "serde_json", "tokio", @@ -493,9 +780,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" [[package]] name = "form_urlencoded" @@ -568,7 +855,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -849,7 +1136,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -961,9 +1248,9 @@ checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "litemap" @@ -983,11 +1270,12 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "3d6ea2a48c204030ee31a7d7fc72c93294c92fe87ecb1789881c9543516e1a0d" dependencies = [ "serde", + "value-bag", ] [[package]] @@ -1105,9 +1393,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.5" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] @@ -1118,293 +1406,16 @@ version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" -[[package]] -name = "opcua" -version = "0.13.0" -dependencies = [ - "async-trait", - "bytes", - "chrono", - "env_logger", - "log", - "opcua", - "opcua-client", - "opcua-core", - "opcua-core-namespace", - "opcua-crypto", - "opcua-macros", - "opcua-nodes", - "opcua-server", - "opcua-types", - "serde_json", - "tempdir", - "tokio", - "tokio-util", -] - -[[package]] -name = "opcua-certificate-creator" -version = "0.13.0" -dependencies = [ - "opcua", - "pico-args", -] - -[[package]] -name = "opcua-chess-server" -version = "0.13.0" -dependencies = [ - "opcua", - "tokio", - "uci", -] - -[[package]] -name = "opcua-client" -version = "0.13.0" -dependencies = [ - "arc-swap", - "async-trait", - "chrono", - "futures", - "hashbrown 0.15.2", - "log", - "opcua-core", - "opcua-crypto", - "opcua-nodes", - "opcua-types", - "opcua-xml", - "parking_lot", - "rsa", - "serde", - "tokio", - "tokio-util", -] - -[[package]] -name = "opcua-codegen" -version = "0.1.0" -dependencies = [ - "base64 0.22.1", - "chrono", - "convert_case", - "log", - "opcua-xml", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "roxmltree", - "serde", - "serde_json", - "serde_yaml", - "syn 2.0.90", - "thiserror", - "uuid", -] - -[[package]] -name = "opcua-core" -version = "0.13.0" -dependencies = [ - "bytes", - "chrono", - "log", - "opcua-crypto", - "opcua-types", - "parking_lot", - "serde", - "serde_yaml", - "thiserror", - "tokio", - "tokio-util", - "url", -] - -[[package]] -name = "opcua-core-namespace" -version = "0.13.0" -dependencies = [ - "opcua-nodes", - "opcua-types", -] - -[[package]] -name = "opcua-crypto" -version = "0.13.0" -dependencies = [ - "aes", - "cbc", - "chrono", - "const-oid", - "gethostname", - "hmac", - "log", - "opcua-types", - "rand 0.8.5", - "rsa", - "serde", - "sha1", - "sha2", - "tempdir", - "x509-cert", -] - -[[package]] -name = "opcua-demo-server" -version = "0.13.0" -dependencies = [ - "chrono", - "log", - "log4rs", - "opcua", - "pico-args", - "rand 0.8.5", - "tokio", - "tokio-util", -] - -[[package]] -name = "opcua-discovery-client" -version = "0.13.0" -dependencies = [ - "opcua", - "pico-args", - "tokio", -] - -[[package]] -name = "opcua-event-client" -version = "0.13.0" -dependencies = [ - "opcua", - "pico-args", - "tokio", -] - -[[package]] -name = "opcua-macros" -version = "0.1.0" -dependencies = [ - "base64 0.22.1", - "convert_case", - "proc-macro2", - "quote", - "syn 2.0.90", - "uuid", -] - -[[package]] -name = "opcua-mqtt-client" -version = "0.13.0" -dependencies = [ - "opcua", - "pico-args", - "rumqttc", - "tokio", -] - -[[package]] -name = "opcua-nodes" -version = "0.13.0" -dependencies = [ - "bitflags", - "hashbrown 0.15.2", - "log", - "opcua-macros", - "opcua-nodes", - "opcua-types", - "opcua-xml", - "regex", - "thiserror", -] - -[[package]] -name = "opcua-server" -version = "0.13.0" -dependencies = [ - "arc-swap", - "async-trait", - "bitflags", - "chrono", - "futures", - "hashbrown 0.15.2", - "log", - "opcua-client", - "opcua-core", - "opcua-core-namespace", - "opcua-crypto", - "opcua-nodes", - "opcua-types", - "parking_lot", - "postcard", - "regex", - "serde", - "serde_json", - "tokio", - "tokio-util", -] - -[[package]] -name = "opcua-simple-client" -version = "0.13.0" -dependencies = [ - "log", - "opcua", - "pico-args", - "tokio", -] - -[[package]] -name = "opcua-simple-server" -version = "0.13.0" -dependencies = [ - "chrono", - "log", - "opcua", - "tokio", -] - [[package]] name = "opcua-structure-client" version = "0.13.0" dependencies = [ + "async-opcua", "log", - "opcua", "pico-args", "tokio", ] -[[package]] -name = "opcua-types" -version = "0.13.0" -dependencies = [ - "base64 0.22.1", - "bitflags", - "byteorder", - "chrono", - "hashbrown 0.15.2", - "log", - "opcua-macros", - "opcua-types", - "opcua-xml", - "regex", - "serde_json", - "struson", - "thiserror", - "uuid", -] - -[[package]] -name = "opcua-xml" -version = "0.1.0" -dependencies = [ - "chrono", - "roxmltree", - "thiserror", - "uuid", -] - [[package]] name = "openssl-probe" version = "0.1.5" @@ -1466,9 +1477,9 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project-lite" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -1527,19 +1538,19 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.25" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +checksum = "483f8c21f64f3ea09fe0f30f5d48c3e8eefe5dac9129f0075f76593b4c1da705" dependencies = [ "proc-macro2", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] @@ -1552,16 +1563,16 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", "version_check", "yansi", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -1758,9 +1769,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.42" +version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ "bitflags", "errno", @@ -1814,9 +1825,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "ryu" @@ -1864,9 +1875,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.13.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1863fd3768cd83c56a7f60faa4dc0d403f1b6df0a38c3c25f44b7894e45370d5" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -1880,9 +1891,9 @@ checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" [[package]] name = "serde" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] @@ -1899,20 +1910,29 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", +] + +[[package]] +name = "serde_fmt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" +dependencies = [ + "serde", ] [[package]] name = "serde_json" -version = "1.0.133" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" dependencies = [ "itoa", "memchr", @@ -1922,9 +1942,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.11.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" +checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" dependencies = [ "base64 0.22.1", "chrono", @@ -1940,14 +1960,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.11.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" +checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -2085,7 +2105,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -2105,6 +2125,84 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "sval" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6dc0f9830c49db20e73273ffae9b5240f63c42e515af1da1fceefb69fceafd8" + +[[package]] +name = "sval_buffer" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "429922f7ad43c0ef8fd7309e14d750e38899e32eb7e8da656ea169dd28ee212f" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f16ff5d839396c11a30019b659b0976348f3803db0626f736764c473b50ff4" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c01c27a80b6151b0557f9ccbe89c11db571dc5f68113690c1e028d7e974bae94" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0deef63c70da622b2a8069d8600cf4b05396459e665862e7bdb290fd6cf3f155" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_nested" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a39ce5976ae1feb814c35d290cf7cf8cd4f045782fe1548d6bc32e21f6156e9f" +dependencies = [ + "sval", + "sval_buffer", + "sval_ref", +] + +[[package]] +name = "sval_ref" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb7c6ee3751795a728bc9316a092023529ffea1783499afbc5c66f5fabebb1fa" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a5572d0321b68109a343634e3a5d576bf131b82180c6c442dee06349dfc652a" +dependencies = [ + "serde", + "sval", + "sval_nested", +] + [[package]] name = "syn" version = "1.0.109" @@ -2118,9 +2216,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.90" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -2135,7 +2233,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -2174,7 +2272,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -2246,14 +2344,14 @@ checksum = "8d9ef545650e79f30233c0003bcc2504d7efac6dad25fca40744de773fe2049c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] name = "tokio" -version = "1.42.0" +version = "1.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" +checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" dependencies = [ "backtrace", "bytes", @@ -2269,13 +2367,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -2301,6 +2399,12 @@ dependencies = [ "tokio", ] +[[package]] +name = "typeid" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" + [[package]] name = "typemap-ors" version = "1.0.0" @@ -2383,13 +2487,49 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +checksum = "b913a3b5fe84142e269d63cc62b64319ccaf89b748fc31fe025177f767a756c4" dependencies = [ "getrandom", ] +[[package]] +name = "value-bag" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb773bd36fd59c7ca6e336c94454d9c66386416734817927ac93d81cb3c5b0b" +dependencies = [ + "erased-serde", + "serde", + "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a916a702cac43a88694c97657d449775667bcd14b70419441d05b7fea4a83a" +dependencies = [ + "sval", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", +] + [[package]] name = "version_check" version = "0.9.5" @@ -2423,7 +2563,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", "wasm-bindgen-shared", ] @@ -2445,7 +2585,7 @@ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2630,7 +2770,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", "synstructure", ] @@ -2652,7 +2792,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -2672,7 +2812,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", "synstructure", ] @@ -2693,7 +2833,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -2715,5 +2855,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] diff --git a/async-opcua-types/src/relative_path.rs b/async-opcua-types/src/relative_path.rs index c6c1cbd4..7eb9b728 100644 --- a/async-opcua-types/src/relative_path.rs +++ b/async-opcua-types/src/relative_path.rs @@ -101,7 +101,10 @@ impl From<&[QualifiedName]> for RelativePath { } } } - +// Cannot use +//impl> TryFrom for RelativePath { +// for some strange reasons so implementing all thee manually here +// impl TryFrom<&str> for RelativePath { type Error = OpcUaError; @@ -110,6 +113,22 @@ impl TryFrom<&str> for RelativePath { } } +impl TryFrom<&String> for RelativePath { + type Error = OpcUaError; + + fn try_from(value: &String) -> Result { + RelativePath::from_str(value, &RelativePathElement::default_node_resolver) + } +} + +impl TryFrom for RelativePath { + type Error = OpcUaError; + + fn try_from(value: String) -> Result { + RelativePath::from_str(&value, &RelativePathElement::default_node_resolver) + } +} + impl<'a> From<&'a RelativePathElement> for String { fn from(element: &'a RelativePathElement) -> String { let mut result = element diff --git a/samples/custom-structures-client/Cargo.toml b/samples/custom-structures-client/Cargo.toml index f3e08784..491f295a 100644 --- a/samples/custom-structures-client/Cargo.toml +++ b/samples/custom-structures-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "opcua-structure-client" -version = "0.13.0" # OPCUARustVersion +version = "0.13.0" # OPCUARustVersion authors = ["Rust-OpcUa contributors"] edition = "2021" @@ -9,8 +9,13 @@ pico-args = "0.5" tokio = { version = "1.36.0", features = ["full"] } log = { workspace = true } -[dependencies.opcua] -path = "../../lib" -version = "0.13.0" # OPCUARustVersion +[dependencies.async-opcua] +path = "../../async-opcua" +version = "0.13.0" # OPCUARustVersion features = ["client", "console-logging"] default-features = false + +[features] +default = ["json", "xml"] +json = ["async-opcua/json"] +xml = ["async-opcua/xml"] diff --git a/samples/custom-structures-client/src/bin/dynamic_client.rs b/samples/custom-structures-client/src/bin/dynamic_client.rs new file mode 100644 index 00000000..46704804 --- /dev/null +++ b/samples/custom-structures-client/src/bin/dynamic_client.rs @@ -0,0 +1,71 @@ +// OPCUA for Rust +// SPDX-License-Identifier: MPL-2.0 +// Copyright (C) 2017-2024 Adam Lock + +//! This simple OPC UA client will do the following: +//! +//! 1. Create a client configuration +//! 2. Connect to an endpoint specified by the url with security None +//! 3. Read a variable on server with data type being a custom structure + +use std::sync::Arc; + +use opcua::{ + client::{custom_types::DataTypeTreeBuilder, Session}, + types::{ + custom::{DynamicStructure, DynamicTypeLoader}, + errors::OpcUaError, + BrowsePath, ObjectId, TimestampsToReturn, TypeLoader, Variant, + }, +}; +use opcua_structure_client::client_connect; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let (session, handle, ns) = client_connect().await?; + read_structure_var(&session, ns).await?; + + session.disconnect().await?; + handle.await.unwrap(); + Ok(()) +} + +async fn read_structure_var(session: &Arc, ns: u16) -> Result<(), OpcUaError> { + let type_tree = DataTypeTreeBuilder::new(|f| f.namespace <= ns) + .build(session) + .await + .unwrap(); + let type_tree = Arc::new(type_tree); + let loader = Arc::new(DynamicTypeLoader::new(type_tree.clone())) as Arc; + session.add_type_loader(loader.clone()); + + let res = session + .translate_browse_paths_to_node_ids(&[BrowsePath { + starting_node: ObjectId::ObjectsFolder.into(), + relative_path: format!("/{}:ErrorData", ns).try_into()?, + }]) + .await?; + let Some(target) = &res[0].targets else { + panic!("translate browse path did not return a NodeId") + }; + + let node_id = &target[0].target_id.node_id; + let dv = session + .read(&[node_id.into()], TimestampsToReturn::Neither, 0.0) + .await? + .into_iter() + .next() + .unwrap(); + dbg!(&dv); + + let Some(Variant::ExtensionObject(val)) = dv.value else { + panic!("Unexpected variant type"); + }; + + let val: DynamicStructure = *val.into_inner_as().unwrap(); + dbg!(&val.get_field(0)); + dbg!(&val.get_field(1)); + dbg!(&val.get_field(2)); + + Ok(()) +} diff --git a/samples/custom-structures-client/src/bin/native_client.rs b/samples/custom-structures-client/src/bin/native_client.rs new file mode 100644 index 00000000..651fafcf --- /dev/null +++ b/samples/custom-structures-client/src/bin/native_client.rs @@ -0,0 +1,170 @@ +use std::sync::Arc; + +use opcua::{ + client::Session, + types::{errors::OpcUaError, BrowsePath, ExpandedNodeId, NodeId, ObjectId, TimestampsToReturn}, +}; +use opcua_structure_client::{client_connect, NAMESPACE_URI}; + +const STRUCT_ENC_TYPE_ID: u32 = 3324; +const STRUCT_DATA_TYPE_ID: u32 = 3325; +//const ENUM_DATA_TYPE_ID: u32 = 3326; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let (session, handle, ns) = client_connect().await?; + read_structure_var(&session, ns).await?; + + session.disconnect().await?; + handle.await.unwrap(); + Ok(()) +} + +async fn read_structure_var(session: &Arc, ns: u16) -> Result<(), OpcUaError> { + session.add_type_loader(Arc::new(CustomTypeLoader)); + + let res = session + .translate_browse_paths_to_node_ids(&[BrowsePath { + starting_node: ObjectId::ObjectsFolder.into(), + relative_path: format!("/{}:ErrorData", ns).try_into()?, + }]) + .await?; + let Some(target) = &res[0].targets else { + panic!("translate browse path did not return a NodeId") + }; + + let node_id = &target[0].target_id.node_id; + let dv = session + .read(&[node_id.into()], TimestampsToReturn::Neither, 0.0) + .await? + .into_iter() + .next() + .unwrap(); + dbg!(&dv); + Ok(()) +} + +// The struct and enum code after this line could/should be shared with demo server, +// but having it here makes the example self-contained. + +#[derive( + Debug, + Copy, + Clone, + PartialEq, + Eq, + opcua::types::UaEnum, + opcua::types::BinaryEncodable, + opcua::types::BinaryDecodable, +)] +#[cfg_attr( + feature = "json", + derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) +)] +#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[derive(Default)] +#[repr(i32)] +pub enum AxisState { + #[default] + Disabled = 1i32, + Enabled = 2i32, + Idle = 3i32, + MoveAbs = 4i32, + Error = 5i32, +} + +#[derive(Debug, Clone, PartialEq, opcua::types::BinaryEncodable, opcua::types::BinaryDecodable)] +#[cfg_attr( + feature = "json", + derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) +)] +#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[derive(Default)] +pub struct ErrorData { + message: opcua::types::UAString, + error_id: u32, + last_state: AxisState, +} + +static TYPES: std::sync::LazyLock = + std::sync::LazyLock::new(|| { + let mut inst = opcua::types::TypeLoaderInstance::new(); + { + inst.add_binary_type( + STRUCT_DATA_TYPE_ID, + STRUCT_ENC_TYPE_ID, + opcua::types::binary_decode_to_enc::, + ); + + inst + } + }); + +#[derive(Debug, Clone, Copy)] +pub struct CustomTypeLoader; +impl opcua::types::TypeLoader for CustomTypeLoader { + fn load_from_binary( + &self, + node_id: &opcua::types::NodeId, + stream: &mut dyn std::io::Read, + ctx: &opcua::types::Context<'_>, + ) -> Option>> { + let idx = ctx.namespaces().get_index(NAMESPACE_URI)?; + if idx != node_id.namespace { + return None; + } + let Some(num_id) = node_id.as_u32() else { + return Some(Err(opcua::types::Error::decoding( + "Unsupported encoding ID. Only numeric encoding IDs are currently supported", + ))); + }; + TYPES.decode_binary(num_id, stream, ctx) + } + #[cfg(feature = "xml")] + fn load_from_xml( + &self, + _node_id: &opcua::types::NodeId, + _stream: &opcua::types::xml::XmlElement, + _ctx: &opcua::types::xml::XmlContext<'_>, + ) -> Option, opcua::types::xml::FromXmlError>> { + todo!() + } + #[cfg(feature = "json")] + fn load_from_json( + &self, + _node_id: &opcua::types::NodeId, + _stream: &mut opcua::types::json::JsonStreamReader<&mut dyn std::io::Read>, + _ctx: &opcua::types::Context<'_>, + ) -> Option>> { + todo!() + } + fn priority(&self) -> opcua::types::TypeLoaderPriority { + opcua::types::TypeLoaderPriority::Generated + } +} + +impl opcua::types::ExpandedMessageInfo for ErrorData { + fn full_type_id(&self) -> opcua::types::ExpandedNodeId { + ExpandedNodeId { + node_id: NodeId::new(0, STRUCT_ENC_TYPE_ID), + namespace_uri: NAMESPACE_URI.into(), + server_index: 0, + } + } + + fn full_json_type_id(&self) -> opcua::types::ExpandedNodeId { + todo!() + } + + fn full_xml_type_id(&self) -> opcua::types::ExpandedNodeId { + todo!() + } + + fn full_data_type_id(&self) -> opcua::types::ExpandedNodeId { + ExpandedNodeId { + node_id: NodeId::new(0, STRUCT_DATA_TYPE_ID), + namespace_uri: NAMESPACE_URI.into(), + server_index: 0, + } + } +} diff --git a/samples/custom-structures-client/src/lib.rs b/samples/custom-structures-client/src/lib.rs new file mode 100644 index 00000000..acd5360e --- /dev/null +++ b/samples/custom-structures-client/src/lib.rs @@ -0,0 +1,85 @@ +use std::sync::Arc; + +use opcua::{ + client::{ClientBuilder, IdentityToken, Session}, + crypto::SecurityPolicy, + types::{MessageSecurityMode, StatusCode, UserTokenPolicy}, +}; +use tokio::task::JoinHandle; + +pub const NAMESPACE_URI: &str = "urn:DemoServer"; + +struct Args { + help: bool, + url: String, +} + +impl Args { + pub fn parse_args() -> Result> { + let mut args = pico_args::Arguments::from_env(); + Ok(Args { + help: args.contains(["-h", "--help"]), + url: args + .opt_value_from_str("--url")? + .unwrap_or_else(|| String::from(DEFAULT_URL)), + }) + } + + pub fn usage() { + println!( + r#"Simple Client +Usage: + -h, --help Show help + --url [url] Url to connect to (default: {})"#, + DEFAULT_URL + ); + } +} + +pub const DEFAULT_URL: &str = "opc.tcp://localhost:4855"; + +pub async fn client_connect( +) -> Result<(Arc, JoinHandle, u16), Box> { + // Read command line arguments + let args = Args::parse_args()?; + if args.help { + Args::usage(); + return Err("Help requested, exiting".into()); + } + // Optional - enable OPC UA logging + opcua::console_logging::init(); + + // Make the client configuration + let mut client = ClientBuilder::new() + .application_name("Simple Client") + .application_uri("urn:SimpleClient") + .product_uri("urn:SimpleClient") + .trust_server_certs(true) + .create_sample_keypair(true) + .session_retry_limit(3) + .client() + .unwrap(); + + let (session, event_loop) = client + .connect_to_matching_endpoint( + ( + args.url.as_ref(), + SecurityPolicy::None.to_str(), + MessageSecurityMode::None, + UserTokenPolicy::anonymous(), + ), + IdentityToken::Anonymous, + ) + .await + .unwrap(); + + let handle = event_loop.spawn(); + session.wait_for_connection().await; + + let ns = session + .get_namespace_index(NAMESPACE_URI) + .await + .map_err(|e| format!("Error getting namespace index {:?}", e))?; + + Ok((session, handle, ns)) +} diff --git a/samples/custom-structures-client/src/main.rs b/samples/custom-structures-client/src/main.rs deleted file mode 100644 index 29643dbc..00000000 --- a/samples/custom-structures-client/src/main.rs +++ /dev/null @@ -1,184 +0,0 @@ -// OPCUA for Rust -// SPDX-License-Identifier: MPL-2.0 -// Copyright (C) 2017-2024 Adam Lock - -//! This simple OPC UA client will do the following: -//! -//! 1. Create a client configuration -//! 2. Connect to an endpoint specified by the url with security None -//! 3. Read a variable on server with data type being a custom structure -use std::sync::Arc; - -use opcua::{ - client::{custom_types::DataTypeTreeBuilder, ClientBuilder, IdentityToken, Session}, - crypto::SecurityPolicy, - types::{ - custom::{DynamicStructure, DynamicTypeLoader}, - errors::OpcUaError, - BrowsePath, MessageSecurityMode, ObjectId, TimestampsToReturn, TypeLoader, UserTokenPolicy, - Variant, - }, -}; - -const NAMESPACE_URI: &str = "urn:DemoServer"; - -struct Args { - help: bool, - url: String, -} - -impl Args { - pub fn parse_args() -> Result> { - let mut args = pico_args::Arguments::from_env(); - Ok(Args { - help: args.contains(["-h", "--help"]), - url: args - .opt_value_from_str("--url")? - .unwrap_or_else(|| String::from(DEFAULT_URL)), - }) - } - - pub fn usage() { - println!( - r#"Simple Client -Usage: - -h, --help Show help - --url [url] Url to connect to (default: {})"#, - DEFAULT_URL - ); - } -} - -const DEFAULT_URL: &str = "opc.tcp://localhost:4855"; - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Read command line arguments - let args = Args::parse_args()?; - if args.help { - Args::usage(); - return Ok(()); - } - // Optional - enable OPC UA logging - opcua::console_logging::init(); - - // Make the client configuration - let mut client = ClientBuilder::new() - .application_name("Simple Client") - .application_uri("urn:SimpleClient") - .product_uri("urn:SimpleClient") - .trust_server_certs(true) - .create_sample_keypair(true) - .session_retry_limit(3) - .client() - .unwrap(); - - let (session, event_loop) = client - .connect_to_matching_endpoint( - ( - args.url.as_ref(), - SecurityPolicy::None.to_str(), - MessageSecurityMode::None, - UserTokenPolicy::anonymous(), - ), - IdentityToken::Anonymous, - ) - .await - .unwrap(); - - let handle = event_loop.spawn(); - session.wait_for_connection().await; - - let ns = session - .get_namespace_index(NAMESPACE_URI) - .await - .map_err(|e| format!("Error getting namespace index {:?}", e))?; - - read_structure_var(&session, ns).await?; - - session.disconnect().await?; - handle.await.unwrap(); - Ok(()) -} - -async fn read_structure_var(session: &Arc, ns: u16) -> Result<(), OpcUaError> { - let type_tree = DataTypeTreeBuilder::new(|f| f.namespace <= ns) - .build(session) - .await - .unwrap(); - let type_tree = Arc::new(type_tree); - let loader = Arc::new(DynamicTypeLoader::new(type_tree.clone())) as Arc; - session.add_type_loader(loader.clone()); - - let res = session - .translate_browse_paths_to_node_ids(&[BrowsePath { - starting_node: ObjectId::ObjectsFolder.into(), - relative_path: "/0:ErrorData".try_into()?, - }]) - .await?; - let Some(target) = &res[0].targets else { - panic!("translate browse path did not return a NodeId") - }; - - let node_id = &target[0].target_id.node_id; - let dv = session - .read(&[node_id.into()], TimestampsToReturn::Neither, 0.0) - .await? - .into_iter() - .next() - .unwrap(); - dbg!(&dv); - - let Some(Variant::ExtensionObject(val)) = dv.value else { - panic!("Unexpected variant type"); - }; - - let val: DynamicStructure = *val.into_inner_as().unwrap(); - dbg!(&val.get_field(0)); - dbg!(&val.get_field(1)); - dbg!(&val.get_field(2)); - - Ok(()) -} - -// The struct and enum code after this line could/should be shared with demo server, -// but having it here makes the example self-contained. - -#[derive( - Debug, - Copy, - Clone, - PartialEq, - Eq, - opcua::types::UaEnum, - opcua::types::BinaryEncodable, - opcua::types::BinaryDecodable, -)] -//#[cfg_attr( -//feature = "json", -//derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) -//)] -//#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] -#[derive(Default)] -#[repr(i32)] -pub enum AxisState { - #[default] - Disabled = 1i32, - Enabled = 2i32, - Idle = 3i32, - MoveAbs = 4i32, - Error = 5i32, -} - -#[derive(Debug, Clone, PartialEq, opcua::types::BinaryEncodable, opcua::types::BinaryDecodable)] -//#[cfg_attr( -//feature = "json", -//derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) -//)] -//#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] -#[derive(Default)] -pub struct ErrorData { - message: opcua::types::UAString, - error_id: u32, - last_state: AxisState, -} diff --git a/samples/demo-server/src/customs.rs b/samples/demo-server/src/customs.rs index 2f8b998a..876f681d 100644 --- a/samples/demo-server/src/customs.rs +++ b/samples/demo-server/src/customs.rs @@ -5,8 +5,8 @@ use opcua::{ server::node_manager::memory::SimpleNodeManager, types::{ DataTypeDefinition, DataTypeId, EnumDefinition, EnumField, ExpandedNodeId, ExtensionObject, - NodeId, ObjectId, ObjectTypeId, ReferenceTypeId, StructureDefinition, StructureField, - StructureType, + NodeId, ObjectId, ObjectTypeId, QualifiedName, ReferenceTypeId, StructureDefinition, + StructureField, StructureType, }, }; @@ -24,11 +24,15 @@ pub fn add_custom_types(nm: Arc, ns: u16) { let mut addr = addr.write(); let error_node = NodeId::next_numeric(ns); let error_data = ErrorData::new("No Error", 98, AxisState::Idle); - VariableBuilder::new(&error_node, "ErrorData", "ErrorData") - .organized_by(ObjectId::ObjectsFolder) - .data_type(struct_id.clone()) - .value(ExtensionObject::new(error_data)) - .insert(&mut *addr); + VariableBuilder::new( + &error_node, + QualifiedName::new(ns, "ErrorData"), + "ErrorData", + ) + .organized_by(ObjectId::ObjectsFolder) + .data_type(struct_id.clone()) + .value(ExtensionObject::new(error_data)) + .insert(&mut *addr); } fn enum_field(name: &str, value: i64) -> EnumField {