From 59f8ac8833b4016a7954e0d1054582f7da00306e Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Fri, 6 Oct 2023 09:48:22 -0700 Subject: [PATCH 01/28] Removed DTDL Parser --- .github/workflows/rust-ci.yml | 26 +- Cargo.toml | 8 +- devops/cg/license_url_to_type.json | 5 + digital-twin-model/dtdl/v3/spec/sdv/bad.json | 17 + dtdl-parser/.accepted_words.txt | 12 - dtdl-parser/Cargo.toml | 26 - dtdl-parser/README.md | 6 - dtdl-parser/dtdl/samples/building.json | 19 - dtdl-parser/dtdl/samples/demo_resources.json | 42 - dtdl-parser/dtdl/samples/phone.json | 23 - dtdl-parser/dtdl/samples/thermostat.json | 19 - dtdl-parser/src/command_info.rs | 15 - dtdl-parser/src/command_info_impl.rs | 274 -- dtdl-parser/src/command_payload_info.rs | 8 - dtdl-parser/src/command_payload_info_impl.rs | 216 -- dtdl-parser/src/complex_schema_info.rs | 8 - dtdl-parser/src/component_info.rs | 12 - dtdl-parser/src/component_info_impl.rs | 208 -- dtdl-parser/src/content_info.rs | 8 - dtdl-parser/src/dtmi.rs | 250 -- dtdl-parser/src/entity_info.rs | 41 - dtdl-parser/src/entity_kind.rs | 110 - dtdl-parser/src/field_info.rs | 8 - dtdl-parser/src/field_info_impl.rs | 221 -- dtdl-parser/src/interface_info.rs | 8 - dtdl-parser/src/interface_info_impl.rs | 159 -- dtdl-parser/src/lib.rs | 40 - dtdl-parser/src/model_dict.rs | 10 - dtdl-parser/src/model_parser.rs | 1175 -------- dtdl-parser/src/named_entity_info.rs | 11 - dtdl-parser/src/object_info.rs | 12 - dtdl-parser/src/object_info_impl.rs | 186 -- dtdl-parser/src/primitive_schema_info.rs | 8 - dtdl-parser/src/primitive_schema_info_impl.rs | 154 - dtdl-parser/src/primitive_schema_kinds.rs | 22 - dtdl-parser/src/property_info.rs | 15 - dtdl-parser/src/property_info_impl.rs | 224 -- dtdl-parser/src/relationship_info.rs | 15 - dtdl-parser/src/relationship_info_impl.rs | 220 -- dtdl-parser/src/schema_field_info.rs | 12 - dtdl-parser/src/schema_info.rs | 8 - dtdl-parser/src/telemetry_info.rs | 12 - dtdl-parser/src/telemetry_info_impl.rs | 213 -- dtdl-tools/Cargo.toml | 9 + dtdl-tools/build.rs | 28 + .../src/dtdl-validator/Directory.Build.props | 7 + .../src/dtdl-validator/DtdlValidator.cs | 105 + .../src/dtdl-validator/dtdl-validator.csproj | 14 + dtdl-tools/src/dtdl-validator/licenses.md | 5 + dtdl-tools/src/lib.rs | 49 + rust-toolchain.toml | 2 +- tmp.out | 2482 +++++++++++++++++ tools/dotnet_append_to_notice.sh | 54 + tools/dotnet_get_licenses.sh | 59 + tools/dotnet_notice_generation.sh | 44 + tools/notice_generation.sh | 4 + 56 files changed, 2895 insertions(+), 4053 deletions(-) create mode 100644 devops/cg/license_url_to_type.json create mode 100644 digital-twin-model/dtdl/v3/spec/sdv/bad.json delete mode 100644 dtdl-parser/.accepted_words.txt delete mode 100644 dtdl-parser/Cargo.toml delete mode 100644 dtdl-parser/README.md delete mode 100644 dtdl-parser/dtdl/samples/building.json delete mode 100644 dtdl-parser/dtdl/samples/demo_resources.json delete mode 100644 dtdl-parser/dtdl/samples/phone.json delete mode 100644 dtdl-parser/dtdl/samples/thermostat.json delete mode 100644 dtdl-parser/src/command_info.rs delete mode 100644 dtdl-parser/src/command_info_impl.rs delete mode 100644 dtdl-parser/src/command_payload_info.rs delete mode 100644 dtdl-parser/src/command_payload_info_impl.rs delete mode 100644 dtdl-parser/src/complex_schema_info.rs delete mode 100644 dtdl-parser/src/component_info.rs delete mode 100644 dtdl-parser/src/component_info_impl.rs delete mode 100644 dtdl-parser/src/content_info.rs delete mode 100644 dtdl-parser/src/dtmi.rs delete mode 100644 dtdl-parser/src/entity_info.rs delete mode 100644 dtdl-parser/src/entity_kind.rs delete mode 100644 dtdl-parser/src/field_info.rs delete mode 100644 dtdl-parser/src/field_info_impl.rs delete mode 100644 dtdl-parser/src/interface_info.rs delete mode 100644 dtdl-parser/src/interface_info_impl.rs delete mode 100644 dtdl-parser/src/lib.rs delete mode 100644 dtdl-parser/src/model_dict.rs delete mode 100644 dtdl-parser/src/model_parser.rs delete mode 100644 dtdl-parser/src/named_entity_info.rs delete mode 100644 dtdl-parser/src/object_info.rs delete mode 100644 dtdl-parser/src/object_info_impl.rs delete mode 100644 dtdl-parser/src/primitive_schema_info.rs delete mode 100644 dtdl-parser/src/primitive_schema_info_impl.rs delete mode 100644 dtdl-parser/src/primitive_schema_kinds.rs delete mode 100644 dtdl-parser/src/property_info.rs delete mode 100644 dtdl-parser/src/property_info_impl.rs delete mode 100644 dtdl-parser/src/relationship_info.rs delete mode 100644 dtdl-parser/src/relationship_info_impl.rs delete mode 100644 dtdl-parser/src/schema_field_info.rs delete mode 100644 dtdl-parser/src/schema_info.rs delete mode 100644 dtdl-parser/src/telemetry_info.rs delete mode 100644 dtdl-parser/src/telemetry_info_impl.rs create mode 100644 dtdl-tools/Cargo.toml create mode 100644 dtdl-tools/build.rs create mode 100644 dtdl-tools/src/dtdl-validator/Directory.Build.props create mode 100644 dtdl-tools/src/dtdl-validator/DtdlValidator.cs create mode 100644 dtdl-tools/src/dtdl-validator/dtdl-validator.csproj create mode 100644 dtdl-tools/src/dtdl-validator/licenses.md create mode 100644 dtdl-tools/src/lib.rs create mode 100644 tmp.out create mode 100755 tools/dotnet_append_to_notice.sh create mode 100755 tools/dotnet_get_licenses.sh create mode 100755 tools/dotnet_notice_generation.sh diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index c5d5780f..d6362598 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -21,23 +21,17 @@ jobs: submodules: recursive - name: Install protobuf-compiler run: sudo apt-get install -y protobuf-compiler - - name: Install nightly Rust toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: nightly-2022-08-11 - default: true - override: true - components: clippy, rustfmt + - name: Install stable Rust toolchain + run: | + rustup show + rustup component add rustfmt clippy - name: Cache Dependencies uses: Swatinem/rust-cache@v2 - - run: cargo check --workspace - # Note: cargo check should use the --locked option - # Excluding it because of this known issue: https://github.com/mozilla/uniffi-rs/issues/1032 + - run: cargo check --workspace --locked - run: cargo clippy --all-targets --all-features --workspace --no-deps -- -D warnings - run: cargo fmt --all -- --check - name: Run doctest only - # we run doctests here as cargo tarpaulin (our test runner) - # requires nightly toolchain to do so + # we run doctest here as cargo tarpaulin (our test runner) uses: actions-rs/cargo@v1 with: command: test @@ -58,12 +52,8 @@ jobs: submodules: recursive - name: Install protobuf-compiler run: sudo apt-get install -y protobuf-compiler - - name: Install nightly Rust toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: nightly-2022-08-11 - default: true - override: true + - name: Install stable Rust toolchain + run: rustup show - name: Cache Dependencies uses: Swatinem/rust-cache@v2 - name: Build diff --git a/Cargo.toml b/Cargo.toml index cc40e80f..43136353 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,12 +17,12 @@ members = [ # extension "core/module/managed_subscribe", + # DTDL tools + "dtdl-tools", + # digital twin model "digital-twin-model", - # DTDL parser - "dtdl-parser", - # samples "samples/common", "samples/protobuf_data_access", @@ -31,7 +31,7 @@ members = [ "samples/mixed", "samples/property", "samples/seat_massager", - "samples/streaming", + # "samples/streaming", ] [workspace.dependencies] diff --git a/devops/cg/license_url_to_type.json b/devops/cg/license_url_to_type.json new file mode 100644 index 00000000..a4f02904 --- /dev/null +++ b/devops/cg/license_url_to_type.json @@ -0,0 +1,5 @@ +{ + "https://raw.githubusercontent.com/moq/moq4/main/License.txt": "BSD 3-Clause", + "https://www.nuget.org/packages/NUnit/3.13.3/License": "MIT", + "https://www.nuget.org/packages/NUnit.Analyzers/3.3.0/License": "MIT" +} \ No newline at end of file diff --git a/digital-twin-model/dtdl/v3/spec/sdv/bad.json b/digital-twin-model/dtdl/v3/spec/sdv/bad.json new file mode 100644 index 00000000..7701a3a3 --- /dev/null +++ b/digital-twin-model/dtdl/v3/spec/sdv/bad.json @@ -0,0 +1,17 @@ +[ + { + "@context": ["dtmi:dtdl:context;3"], + "@type": "DeeInterface", + "@id": "dtmi:sdv:OBD;1", + "description": "On-board Diagnostics Interface", + "contents": [ + { + "@type": "Property", + "@id": "dtmi:sdv:OBD:HybridBatteryRemaining;1", + "name": "HybridBatteryRemaining", + "description": "The remaining hybrid battery life.", + "schema": "integer" + } + ] + } +] diff --git a/dtdl-parser/.accepted_words.txt b/dtdl-parser/.accepted_words.txt deleted file mode 100644 index a0e25ad9..00000000 --- a/dtdl-parser/.accepted_words.txt +++ /dev/null @@ -1,12 +0,0 @@ -api -com -DTDL -digitaltwins -dtdl -en -github -https -javascript -js -microsoft -sdk diff --git a/dtdl-parser/Cargo.toml b/dtdl-parser/Cargo.toml deleted file mode 100644 index 1347b654..00000000 --- a/dtdl-parser/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT license. -# SPDX-License-Identifier: MIT - -[package] -name = "dtdl-parser" -version = "0.1.0" -edition = "2021" -license = "MIT" - -[dependencies] -async-std = { workspace = true, features = ["attributes"] } -futures = { workspace = true } -generic-json = { workspace = true, features = ["serde_json-impl"] } -iref = { workspace = true } -json-ld = { git = "https://github.com/blast-hardcheese/json-ld", branch = "resolve-issue-40" } -lazy_static = { workspace = true } -log = { workspace = true } -regex = { workspace = true } -serde_json = { workspace = true } -strum = { workspace = true } -strum_macros = { workspace = true } - -[lib] -path = "src/lib.rs" -crate-type = ["lib"] \ No newline at end of file diff --git a/dtdl-parser/README.md b/dtdl-parser/README.md deleted file mode 100644 index 545000de..00000000 --- a/dtdl-parser/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# DTDL Parser - -## Overview - -This is a Rust DTDL Parser, based on the JavaScript DTDL Parser's [code](https://github.com/Azure/azure-sdk-for-js/tree/%40azure/dtdl-parser_1.0.0-beta.2/sdk/digitaltwins/dtdl-parser) -and [API](https://learn.microsoft.com/en-us/javascript/api/@azure/dtdl-parser). Currently, the Rust DTDL Parser only provides a subset of the functionality of the JavaScript DTDL Parser. diff --git a/dtdl-parser/dtdl/samples/building.json b/dtdl-parser/dtdl/samples/building.json deleted file mode 100644 index 500bc7ed..00000000 --- a/dtdl-parser/dtdl/samples/building.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "@id": "dtmi:com:example:Building;1", - "@type": "Interface", - "displayName": "Building", - "contents": [ - { - "@type": "Property", - "name": "name", - "schema": "string", - "writable": true - }, - { - "@type": "Relationship", - "name": "contains", - "target": "dtmi:com:example:Room;1" - } - ], - "@context": "dtmi:dtdl:context;3" -} diff --git a/dtdl-parser/dtdl/samples/demo_resources.json b/dtdl-parser/dtdl/samples/demo_resources.json deleted file mode 100644 index 9f401c55..00000000 --- a/dtdl-parser/dtdl/samples/demo_resources.json +++ /dev/null @@ -1,42 +0,0 @@ -[ - { - "@context": ["dtmi:dtdl:context;2", "dtmi:sdv:context;2"], - "@type": "Interface", - "@id": "dtmi:sdv:Vehicle:Cabin:HVAC;1", - "contents": [ - { - "@type": ["Property", "Temperature", "RemotelyAccessible"], - "@id": "dtmi:sdv:Vehicle:Cabin:HVAC:AmbientAirTemperature;1", - "name": "Cabin_AmbientAirTemperature", - "description": "The immediate surroundings air temperature (in Fahrenheit).", - "schema": "double", - "unit": "degreeFahrenheit", - "remote_access": [ - { - "@type": "Endpoint", - "uri": "http://[::1]:40010", - "operations": [ "Get", "Set", "Subscribe", "Unsubscribe" ] - } - ] - }, - { - "@type": ["Command", "RemotelyAccessible"], - "@id": "dtmi:sdv:Vehicle:Cabin:HVAC:SendNotification;1", - "name": "HVAC_send_notification", - "request": { - "name": "send_notification", - "displayName": "send_notification", - "description": "Send a notification to the HVAC.", - "schema": "string" - }, - "remote_access": [ - { - "@type": "Endpoint", - "uri": "http://[::1]:40010", - "operations": [ "Invoke" ] - } - ] - } - ] - } -] diff --git a/dtdl-parser/dtdl/samples/phone.json b/dtdl-parser/dtdl/samples/phone.json deleted file mode 100644 index 18c30fc9..00000000 --- a/dtdl-parser/dtdl/samples/phone.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "@id": "dtmi:com:example:Phone;2", - "@type": "Interface", - "displayName": "Phone", - "contents": [ - { - "@type": "Component", - "name": "frontCamera", - "schema": "dtmi:com:example:Camera;3" - }, - { - "@type": "Component", - "name": "backCamera", - "schema": "dtmi:com:example:Camera;3" - }, - { - "@type": "Component", - "name": "deviceInfo", - "schema": "dtmi:azure:deviceManagement:DeviceInformation;2" - } - ], - "@context": "dtmi:dtdl:context;3" -} diff --git a/dtdl-parser/dtdl/samples/thermostat.json b/dtdl-parser/dtdl/samples/thermostat.json deleted file mode 100644 index 654fc7e9..00000000 --- a/dtdl-parser/dtdl/samples/thermostat.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "@id": "dtmi:com:example:Thermostat;1", - "@type": "Interface", - "displayName": "Thermostat", - "contents": [ - { - "@type": "Telemetry", - "name": "temp", - "schema": "double" - }, - { - "@type": "Property", - "name": "setPointTemp", - "writable": true, - "schema": "double" - } - ], - "@context": "dtmi:dtdl:context;3" -} diff --git a/dtdl-parser/src/command_info.rs b/dtdl-parser/src/command_info.rs deleted file mode 100644 index 9585bad1..00000000 --- a/dtdl-parser/src/command_info.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::command_payload_info::CommandPayloadInfo; -use crate::content_info::ContentInfo; - -/// A command is a method that can be invoked on a digital twin. -pub trait CommandInfo: ContentInfo { - /// Returns the request. - fn request(&self) -> &Option>; - - /// Returns the response. - fn response(&self) -> &Option>; -} diff --git a/dtdl-parser/src/command_info_impl.rs b/dtdl-parser/src/command_info_impl.rs deleted file mode 100644 index 5afc6093..00000000 --- a/dtdl-parser/src/command_info_impl.rs +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use serde_json::Value; -use std::any::Any; -use std::collections::HashMap; - -use crate::command_info::CommandInfo; -use crate::command_payload_info::CommandPayloadInfo; -use crate::content_info::ContentInfo; -use crate::dtmi::Dtmi; -use crate::entity_info::EntityInfo; -use crate::entity_kind::EntityKind; -use crate::named_entity_info::NamedEntityInfo; - -pub struct CommandInfoImpl { - // EntityInfo - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - description: Option, - display_name: Option, - undefined_properties: HashMap, - - // NamedEntityInfo - name: Option, - - // CommandInfo - request: Option>, - response: Option>, -} - -impl CommandInfoImpl { - /// Returns a new CommandInfoImpl. - /// - /// # Arguments - /// * `dtdl_version` - The DTDL version used to define the command. - /// * `id` - The identifier. - /// * `child_of` - The identifier of the parent element in which this command is defined. - /// * `defined_in` - The identifier of the partition in which this command is defined. - /// * `name` - The name. - /// * `request` - The request. - /// * `response` - The response. - pub fn new( - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - name: Option, - request: Option>, - response: Option>, - ) -> Self { - Self { - dtdl_version, - id, - child_of, - defined_in, - description: None, - display_name: None, - undefined_properties: HashMap::::new(), - name, - request, - response, - } - } - - /// Add an undefined property. - /// # Arguments - /// * `key` - The property's name. - /// * `value` - The property's value. - pub fn add_undefined_property(&mut self, key: String, value: Value) { - self.undefined_properties.insert(key, value); - } -} - -impl EntityInfo for CommandInfoImpl { - /// Returns the DTDL version. - fn dtdl_version(&self) -> i32 { - self.dtdl_version - } - - /// Returns the identifier. - fn id(&self) -> &Dtmi { - &self.id - } - - /// Returns the kind of entity. - fn entity_kind(&self) -> EntityKind { - EntityKind::Command - } - - /// Returns the parent's identifier. - fn child_of(&self) -> &Option { - &self.child_of - } - - /// Returns the enclosing partition's identifier. - fn defined_in(&self) -> &Option { - &self.defined_in - } - - // Returns the description for this entity. - fn description(&self) -> &Option { - &self.description - } - - // Returns the display name for this entity. - fn display_name(&self) -> &Option { - &self.display_name - } - - /// Returns all undefined properties. - fn undefined_properties(&self) -> &HashMap { - &self.undefined_properties - } - - /// Returns the instance as an Any. - fn as_any(&self) -> &dyn Any { - self - } -} - -impl NamedEntityInfo for CommandInfoImpl { - /// Returns the name. - fn name(&self) -> &Option { - &self.name - } -} - -impl ContentInfo for CommandInfoImpl {} - -impl CommandInfo for CommandInfoImpl { - /// Returns the request. - fn request(&self) -> &Option> { - &self.request - } - - /// Returns the response. - fn response(&self) -> &Option> { - &self.response - } -} - -#[cfg(test)] -mod command_info_impl_tests { - use super::*; - use crate::command_payload_info_impl::CommandPayloadInfoImpl; - use crate::dtmi::{create_dtmi, Dtmi}; - use crate::model_parser::DTDL_VERSION; - use crate::primitive_schema_info_impl::PrimitiveSchemaInfoImpl; - use serde_json; - - #[test] - fn new_command_info_impl_test() -> Result<(), String> { - let id_result: Option = - create_dtmi("dtmi:com.example:command:HVAC:send_notification;1"); - assert!(id_result.is_some()); - let id = id_result.unwrap(); - - let child_of_result: Option = create_dtmi("dtmi:com:example:HVAC;1.0"); - assert!(child_of_result.is_some()); - let child_of = child_of_result.unwrap(); - - let defined_in_result: Option = create_dtmi("dtmi:com:example;1.0"); - assert!(defined_in_result.is_some()); - let defined_in = defined_in_result.unwrap(); - - let first_propery_value: Value = serde_json::from_str("{\"first\": \"this\"}").unwrap(); - let second_propery_value: Value = serde_json::from_str("{\"second\": \"that\"}").unwrap(); - - let string_schema_info_id: Option = create_dtmi("dtmi:dtdl:class:String;2"); - assert!(string_schema_info_id.is_some()); - let string_schema_info = Box::new(PrimitiveSchemaInfoImpl::new( - DTDL_VERSION, - string_schema_info_id.unwrap(), - None, - None, - EntityKind::String, - )); - - let integer_schema_info_id: Option = create_dtmi("dtmi:dtdl:class:Integer;2"); - assert!(integer_schema_info_id.is_some()); - let integer_schema_info = Box::new(PrimitiveSchemaInfoImpl::new( - DTDL_VERSION, - integer_schema_info_id.unwrap(), - None, - None, - EntityKind::Integer, - )); - - let request_id: Option = create_dtmi("dtmi:com:example:send_notification:request:1"); - assert!(request_id.is_some()); - let request = Box::new(CommandPayloadInfoImpl::new( - DTDL_VERSION, - request_id.unwrap(), - None, - None, - None, - Some(string_schema_info), - )); - - let response_id: Option = - create_dtmi("dtmi:com:example:send_notification:response:1"); - assert!(response_id.is_some()); - let response = Box::new(CommandPayloadInfoImpl::new( - DTDL_VERSION, - response_id.unwrap(), - None, - None, - None, - Some(integer_schema_info), - )); - - let mut command_info = CommandInfoImpl::new( - DTDL_VERSION, - id.clone(), - Some(child_of.clone()), - Some(defined_in.clone()), - Some(String::from("one")), - Some(request), - Some(response), - ); - command_info.add_undefined_property(String::from("first"), first_propery_value.clone()); - command_info.add_undefined_property(String::from("second"), second_propery_value.clone()); - - assert_eq!(command_info.dtdl_version(), 2); - assert_eq!(command_info.id(), &id); - assert!(command_info.child_of().is_some()); - assert_eq!(command_info.child_of().clone().unwrap(), child_of); - assert!(command_info.defined_in().is_some()); - assert_eq!(command_info.defined_in().clone().unwrap(), defined_in); - assert_eq!(command_info.entity_kind(), EntityKind::Command); - assert_eq!(command_info.undefined_properties().len(), 2); - assert_eq!( - command_info.undefined_properties().get("first").unwrap().clone(), - first_propery_value - ); - assert_eq!( - command_info.undefined_properties().get("second").unwrap().clone(), - second_propery_value - ); - - match command_info.name() { - Some(name) => assert_eq!(name, "one"), - None => return Err(String::from("name has not been set")), - } - - match command_info.request() { - Some(request) => { - assert_eq!(request.entity_kind(), EntityKind::CommandPayload); - match request.schema() { - Some(schema) => assert_eq!(schema.entity_kind(), EntityKind::String), - None => return Err(String::from("request's schema has not been set")), - } - } - None => return Err(String::from("request has not been set")), - } - - match command_info.response() { - Some(response) => { - assert_eq!(response.entity_kind(), EntityKind::CommandPayload); - match response.schema() { - Some(schema) => assert_eq!(schema.entity_kind(), EntityKind::Integer), - None => return Err(String::from("response's schema has not been set")), - } - } - None => return Err(String::from("request has not been set")), - } - - Ok(()) - } -} diff --git a/dtdl-parser/src/command_payload_info.rs b/dtdl-parser/src/command_payload_info.rs deleted file mode 100644 index 7e1ab1bc..00000000 --- a/dtdl-parser/src/command_payload_info.rs +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::schema_field_info::SchemaFieldInfo; - -/// A command payload specifies the inputs and outputs for a command. -pub trait CommandPayloadInfo: SchemaFieldInfo {} diff --git a/dtdl-parser/src/command_payload_info_impl.rs b/dtdl-parser/src/command_payload_info_impl.rs deleted file mode 100644 index bef167ec..00000000 --- a/dtdl-parser/src/command_payload_info_impl.rs +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use serde_json::Value; -use std::any::Any; -use std::collections::HashMap; - -use crate::command_payload_info::CommandPayloadInfo; -use crate::dtmi::Dtmi; -use crate::entity_info::EntityInfo; -use crate::entity_kind::EntityKind; -use crate::named_entity_info::NamedEntityInfo; -use crate::schema_field_info::SchemaFieldInfo; -use crate::schema_info::SchemaInfo; - -pub struct CommandPayloadInfoImpl { - // EntityInfo - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - description: Option, - display_name: Option, - undefined_properties: HashMap, - - // NamedEntityInfo - name: Option, - - // SchemaFieldInfo - schema: Option>, -} - -impl CommandPayloadInfoImpl { - /// Returns a new CommandPayloadInfoImpl. - /// - /// # Arguments - /// * `dtdl_version` - The DTDL version used to define the command payload. - /// * `id` - The identifier. - /// * `child_of` - The identifier of the parent element in which this command payload is defined. - /// * `defined_in` - The identifier of the partition in which this command payload is defined. - /// * `name` - The name. - /// * `schema` - The schema. - pub fn new( - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - name: Option, - schema: Option>, - ) -> Self { - Self { - dtdl_version, - id, - child_of, - defined_in, - description: None, - display_name: None, - undefined_properties: HashMap::::new(), - name, - schema, - } - } - - /// Add an undefined property. - /// # Arguments - /// * `key` - The property's name. - /// * `value` - The property's value. - pub fn add_undefined_property(&mut self, key: String, value: Value) { - self.undefined_properties.insert(key, value); - } -} - -impl EntityInfo for CommandPayloadInfoImpl { - /// Returns the DTDL version. - fn dtdl_version(&self) -> i32 { - self.dtdl_version - } - - /// Returns the identifier. - fn id(&self) -> &Dtmi { - &self.id - } - - /// Returns the kind of entity. - fn entity_kind(&self) -> EntityKind { - EntityKind::CommandPayload - } - - /// Returns the parent's identifier. - fn child_of(&self) -> &Option { - &self.child_of - } - - /// Returns the enclosing partition's identifider. - fn defined_in(&self) -> &Option { - &self.defined_in - } - - // Returns the description for this entity. - fn description(&self) -> &Option { - &self.description - } - - // Returns the display name for this entity. - fn display_name(&self) -> &Option { - &self.display_name - } - - /// Returns all undefined properties. - fn undefined_properties(&self) -> &HashMap { - &self.undefined_properties - } - - /// Returns the instance as an Any. - fn as_any(&self) -> &dyn Any { - self - } -} - -impl NamedEntityInfo for CommandPayloadInfoImpl { - /// Returns the name. - fn name(&self) -> &Option { - &self.name - } -} - -impl SchemaFieldInfo for CommandPayloadInfoImpl { - /// Returns the schema. - fn schema(&self) -> &Option> { - &self.schema - } -} - -impl CommandPayloadInfo for CommandPayloadInfoImpl {} - -#[cfg(test)] -mod command_payload_info_impl_tests { - use super::*; - use crate::dtmi::{create_dtmi, Dtmi}; - use crate::model_parser::DTDL_VERSION; - use crate::primitive_schema_info_impl::PrimitiveSchemaInfoImpl; - use serde_json; - - #[test] - fn new_command_payload_info_impl_test() -> Result<(), String> { - let id_result: Option = create_dtmi("dtmi:com:example:send_notification:request;1.0"); - assert!(id_result.is_some()); - let id = id_result.unwrap(); - - let child_of_result: Option = create_dtmi("dtmi:com:example:HVAC;1.0"); - assert!(child_of_result.is_some()); - let child_of = child_of_result.unwrap(); - - let defined_in_result: Option = create_dtmi("dtmi:com:example;1.0"); - assert!(defined_in_result.is_some()); - let defined_in = defined_in_result.unwrap(); - - let first_propery_value: Value = serde_json::from_str("{\"first\": \"this\"}").unwrap(); - let second_propery_value: Value = serde_json::from_str("{\"second\": \"that\"}").unwrap(); - - let schema_info_id: Option = create_dtmi("dtmi:dtdl:class:String;2"); - assert!(schema_info_id.is_some()); - - let boxed_schema_info = Box::new(PrimitiveSchemaInfoImpl::new( - DTDL_VERSION, - schema_info_id.unwrap(), - None, - None, - EntityKind::String, - )); - - let mut command_payload_info = CommandPayloadInfoImpl::new( - DTDL_VERSION, - id.clone(), - Some(child_of.clone()), - Some(defined_in.clone()), - Some(String::from("one")), - Some(boxed_schema_info), - ); - command_payload_info - .add_undefined_property(String::from("first"), first_propery_value.clone()); - command_payload_info - .add_undefined_property(String::from("second"), second_propery_value.clone()); - - assert_eq!(command_payload_info.dtdl_version(), DTDL_VERSION); - assert_eq!(command_payload_info.id(), &id); - assert!(command_payload_info.child_of().is_some()); - assert_eq!(command_payload_info.child_of().clone().unwrap(), child_of); - assert!(command_payload_info.defined_in().is_some()); - assert_eq!(command_payload_info.defined_in().clone().unwrap(), defined_in); - assert_eq!(command_payload_info.entity_kind(), EntityKind::CommandPayload); - assert!(command_payload_info.schema().is_some()); - match command_payload_info.schema() { - Some(schema) => assert_eq!(schema.entity_kind(), EntityKind::String), - None => return Err(String::from("schema has not been set")), - } - - assert_eq!(command_payload_info.undefined_properties().len(), 2); - assert_eq!( - command_payload_info.undefined_properties().get("first").unwrap().clone(), - first_propery_value - ); - assert_eq!( - command_payload_info.undefined_properties().get("second").unwrap().clone(), - second_propery_value - ); - - match command_payload_info.name() { - Some(name) => assert_eq!(name, "one"), - None => return Err(String::from("name has not been set")), - } - - Ok(()) - } -} diff --git a/dtdl-parser/src/complex_schema_info.rs b/dtdl-parser/src/complex_schema_info.rs deleted file mode 100644 index 07c36870..00000000 --- a/dtdl-parser/src/complex_schema_info.rs +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::schema_info::SchemaInfo; - -/// A complex schema is the base trait for all complex schemas, like object, map and array. -pub trait ComplexSchemaInfo: SchemaInfo {} diff --git a/dtdl-parser/src/component_info.rs b/dtdl-parser/src/component_info.rs deleted file mode 100644 index 09469211..00000000 --- a/dtdl-parser/src/component_info.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::content_info::ContentInfo; -use crate::interface_info::InterfaceInfo; - -/// A component specifies a reference to an interface. It allows interfaces to contain other interfaces. -pub trait ComponentInfo: ContentInfo { - /// Returns the interface, the component uses the term "schema" to refer to it. - fn schema(&self) -> &Option>; -} diff --git a/dtdl-parser/src/component_info_impl.rs b/dtdl-parser/src/component_info_impl.rs deleted file mode 100644 index cb3fb200..00000000 --- a/dtdl-parser/src/component_info_impl.rs +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use serde_json::Value; -use std::any::Any; -use std::collections::HashMap; - -use crate::component_info::ComponentInfo; -use crate::content_info::ContentInfo; -use crate::dtmi::Dtmi; -use crate::entity_info::EntityInfo; -use crate::entity_kind::EntityKind; -use crate::interface_info::InterfaceInfo; -use crate::named_entity_info::NamedEntityInfo; - -pub struct ComponentInfoImpl { - // EntityInfo - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - description: Option, - display_name: Option, - undefined_properties: HashMap, - - // NamedEntityInfo - name: Option, - - // ComponentInfo - schema: Option>, -} - -impl ComponentInfoImpl { - /// Returns a new ComponentInfoImpl. - /// - /// # Arguments - /// * `dtdl_version` - The DTDL version used to define the component. - /// * `id` - The identifier. - /// * `child_of` - The identifier of the parent element in which this component is defined. - /// * `defined_in` - The identifier of the partition in which this component is defined. - /// * `name` - The name. - /// * `schema` - The interface. - pub fn new( - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - name: Option, - schema: Option>, - ) -> Self { - Self { - dtdl_version, - id, - child_of, - defined_in, - description: None, - display_name: None, - undefined_properties: HashMap::::new(), - name, - schema, - } - } - - /// Add an undefined property. - /// # Arguments - /// * `key` - The property's name. - /// * `value` - The property's value. - pub fn add_undefined_property(&mut self, key: String, value: Value) { - self.undefined_properties.insert(key, value); - } -} - -impl EntityInfo for ComponentInfoImpl { - /// Returns the DTDL version. - fn dtdl_version(&self) -> i32 { - self.dtdl_version - } - - /// Returns the identifier. - fn id(&self) -> &Dtmi { - &self.id - } - - /// Returns the kind of entity. - fn entity_kind(&self) -> EntityKind { - EntityKind::Component - } - - /// Returns the parent's identifier. - fn child_of(&self) -> &Option { - &self.child_of - } - - /// Returns the enclosing partition's identifier. - fn defined_in(&self) -> &Option { - &self.defined_in - } - - // Returns the description for this entity. - fn description(&self) -> &Option { - &self.description - } - - // Returns the display name for this entity. - fn display_name(&self) -> &Option { - &self.display_name - } - - /// Returns all undefined properties. - fn undefined_properties(&self) -> &HashMap { - &self.undefined_properties - } - - /// Returns the instance as an Any. - fn as_any(&self) -> &dyn Any { - self - } -} - -impl NamedEntityInfo for ComponentInfoImpl { - /// Returns the name. - fn name(&self) -> &Option { - &self.name - } -} - -impl ContentInfo for ComponentInfoImpl {} - -impl ComponentInfo for ComponentInfoImpl { - /// Returns the interface. - fn schema(&self) -> &Option> { - &self.schema - } -} - -#[cfg(test)] -mod component_info_impl_tests { - use super::*; - use crate::dtmi::{create_dtmi, Dtmi}; - use crate::interface_info_impl::InterfaceInfoImpl; - use crate::model_parser::DTDL_VERSION; - use serde_json; - - #[test] - fn new_component_info_impl_test() -> Result<(), String> { - let id_result: Option = create_dtmi("dtmi:com:example:Thermostat;1.0"); - assert!(id_result.is_some()); - let id = id_result.unwrap(); - - let child_of_result: Option = create_dtmi("dtmi:com:example:Cabin;1.0"); - assert!(child_of_result.is_some()); - let child_of = child_of_result.unwrap(); - - let defined_in_result: Option = create_dtmi("dtmi:com:example:Something;1.0"); - assert!(defined_in_result.is_some()); - let defined_in = defined_in_result.unwrap(); - - let first_propery_value: Value = serde_json::from_str("{\"first\": \"this\"}").unwrap(); - let second_propery_value: Value = serde_json::from_str("{\"second\": \"that\"}").unwrap(); - - let schema_info_id: Option = create_dtmi("dtmi:dtdl:class:String;2"); - assert!(schema_info_id.is_some()); - - let boxed_interface_info = - Box::new(InterfaceInfoImpl::new(DTDL_VERSION, schema_info_id.unwrap(), None, None)); - - let mut component_info = ComponentInfoImpl::new( - DTDL_VERSION, - id.clone(), - Some(child_of.clone()), - Some(defined_in.clone()), - Some(String::from("one")), - Some(boxed_interface_info), - ); - component_info.add_undefined_property(String::from("first"), first_propery_value.clone()); - component_info.add_undefined_property(String::from("second"), second_propery_value.clone()); - - assert_eq!(component_info.dtdl_version(), 2); - assert_eq!(component_info.id(), &id); - assert!(component_info.child_of().is_some()); - assert_eq!(component_info.child_of().clone().unwrap(), child_of); - assert!(component_info.defined_in().is_some()); - assert_eq!(component_info.defined_in().clone().unwrap(), defined_in); - assert_eq!(component_info.entity_kind(), EntityKind::Component); - assert_eq!(component_info.undefined_properties().len(), 2); - assert_eq!( - component_info.undefined_properties().get("first").unwrap().clone(), - first_propery_value - ); - assert_eq!( - component_info.undefined_properties().get("second").unwrap().clone(), - second_propery_value - ); - - match component_info.name() { - Some(name) => assert_eq!(name, "one"), - None => return Err(String::from("name has not been set")), - } - - match component_info.schema() { - Some(schema) => assert_eq!(schema.entity_kind(), EntityKind::Interface), - None => return Err(String::from("schema has not been set")), - } - - Ok(()) - } -} diff --git a/dtdl-parser/src/content_info.rs b/dtdl-parser/src/content_info.rs deleted file mode 100644 index 21a030da..00000000 --- a/dtdl-parser/src/content_info.rs +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::named_entity_info::NamedEntityInfo; - -/// An abstract trait that represents entites that have content. -pub trait ContentInfo: NamedEntityInfo {} diff --git a/dtdl-parser/src/dtmi.rs b/dtdl-parser/src/dtmi.rs deleted file mode 100644 index 9bc6f23d..00000000 --- a/dtdl-parser/src/dtmi.rs +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use iref::Iri; -use log::warn; -use regex::Regex; -use std::fmt; - -lazy_static! { - pub static ref DTMI_REGEX: Regex = - Regex::new(r"^dtmi:[^;]+(;[1-9][0-9]*(\.[0-9][1-9]*)?)?(#[^ ]*)?$").unwrap(); -} - -/// Digital Twin Model Identifier (DTMI). -#[derive(Debug, Default, Clone, Hash, Eq, PartialEq)] -pub struct Dtmi { - value: String, - major_version: Option, - minor_version: Option, - versionless: String, - labels: Vec, - absolute_path: String, - fragment: String, -} - -impl Dtmi { - /// Returns a new DTMI instance. - /// - /// # Arguments - /// * `value` - The string representation of the DTMI. - pub fn new(value: &str) -> Result { - let new_iri_result = Iri::new(value); - if new_iri_result.is_err() { - return Err(format!("The value '{value}' does not represent a valid IRI")); - } - let iri = new_iri_result.unwrap(); - - let mut major_version: Option = None; - let mut minor_version: Option = None; - let absolute_path: String; - - let iri_path_parts: Vec<&str> = iri.path().into_str().split(';').collect(); - if iri_path_parts.len() == 1 { - // no version - absolute_path = String::from(iri_path_parts[0]); - } else if iri_path_parts.len() == 2 { - absolute_path = String::from(iri_path_parts[0]); - let version_parts: Vec<&str> = iri_path_parts[1].split('.').collect(); - if version_parts.len() == 1 { - // no minor version number - if let Ok(value) = version_parts[0].parse::() { - major_version = Some(value) - } - } else if version_parts.len() == 2 { - if let Ok(value) = version_parts[0].parse::() { - major_version = Some(value) - } - if let Ok(value) = version_parts[1].parse::() { - minor_version = Some(value) - } - } else { - return Err(format!("The value '{value}' has an invalid version")); - } - } else { - return Err(format!("The value '{value}' represents an invalid DTMI")); - } - - let versionless: String = format!("dtmi:{absolute_path}"); - - let labels: Vec = absolute_path.split(':').map(Into::into).collect(); - - let fragment = match iri.fragment() { - Some(fragment) => String::from(fragment.as_str()), - None => String::new(), - }; - - Ok(Self { - value: String::from(value), - major_version, - minor_version, - versionless, - labels, - absolute_path, - fragment, - }) - } - - /// Gets the string representation of the DTMI. - pub fn value(&self) -> &str { - &self.value - } - - /// Gets the major version of the DTMI. - pub fn major_version(&self) -> &Option { - &self.major_version - } - - /// Gets the minor version of the DTMI. - pub fn minor_version(&self) -> &Option { - &self.minor_version - } - - /// Gets the major and minor version of the DTMI. - pub fn complete_version(&self) -> f64 { - let major_version: f64 = match self.major_version { - Some(value) => value.into(), - None => 0.0, - }; - - let minor_version: f64 = match self.minor_version { - Some(value) => value.into(), - None => 0.0, - }; - - major_version + minor_version * 0.000001 - } - - /// Gets the portion of the DTMI that preceeds the version number. - pub fn versionless(&self) -> &str { - &self.versionless - } - - /// Gets the sequence of labels in the path portion of the DTMI. - pub fn labels(&self) -> &Vec { - &self.labels - } - - /// Gets the absolute path of the DTMI. - pub fn absolute_path(&self) -> &str { - &self.absolute_path - } - - /// Gets the name of the DTMI's fragment, which is the empty string if there is no fragment. - pub fn fragment(&self) -> &str { - &self.fragment - } -} - -impl fmt::Display for Dtmi { - /// Format support for DTMI. - /// - /// # Arguments - /// * `f` - The associated formatter. - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.value()) - } -} - -/// Create a new DTMI instance. -/// -/// # Arguments -/// * `value` - The IRI to copy from. -pub fn create_dtmi(value: &str) -> Option { - if !DTMI_REGEX.is_match(value) { - warn!("The value '{value}' does not represent a valid DTMI"); - return None; - } - - let new_dtmi_result = Dtmi::new(value); - if let Err(error) = new_dtmi_result { - warn!("{error}"); - return None; - } - - Some(new_dtmi_result.unwrap()) -} - -#[cfg(test)] -mod dmti_tests { - use super::*; - - #[test] - fn new_dtmi_test() { - let mut new_dtmi_result = Dtmi::new("dtmi:com:example:Thermostat;1.234#some-fragment"); - assert!(new_dtmi_result.is_ok()); - let mut dtmi: Dtmi = new_dtmi_result.unwrap(); - assert!(dtmi.major_version().is_some()); - assert_eq!(dtmi.major_version().unwrap(), 1); - assert!(dtmi.minor_version().is_some()); - assert_eq!(dtmi.minor_version().unwrap(), 234); - assert_eq!(dtmi.complete_version(), 1.000234); - assert_eq!(dtmi.versionless(), "dtmi:com:example:Thermostat"); - assert_eq!(dtmi.labels().len(), 3); - assert_eq!(dtmi.labels()[0], "com"); - assert_eq!(dtmi.labels()[1], "example"); - assert_eq!(dtmi.labels()[2], "Thermostat"); - assert_eq!(dtmi.absolute_path, "com:example:Thermostat"); - assert_eq!(dtmi.fragment(), "some-fragment"); - assert_eq!(format!("{dtmi}"), "dtmi:com:example:Thermostat;1.234#some-fragment"); - - new_dtmi_result = Dtmi::new("dtmi:com:example:Thermostat;1.234#"); - assert!(new_dtmi_result.is_ok()); - dtmi = new_dtmi_result.unwrap(); - assert_eq!(dtmi.fragment(), ""); - assert_eq!(format!("{dtmi}"), "dtmi:com:example:Thermostat;1.234#"); - } - - #[test] - fn create_dtmi_test() { - let create_dtmi_result: Option = create_dtmi("dtmi:com:example:Thermostat;1.234567"); - assert!(create_dtmi_result.is_some()); - let dtmi = create_dtmi_result.unwrap(); - assert!(dtmi.major_version().is_some()); - assert!(dtmi.major_version().unwrap() == 1); - assert!(dtmi.minor_version().is_some()); - assert!(dtmi.minor_version().unwrap() == 234567); - assert_eq!(dtmi.complete_version(), 1.234567); - assert_eq!(dtmi.versionless(), "dtmi:com:example:Thermostat"); - assert_eq!(dtmi.labels().len(), 3); - assert_eq!(dtmi.labels()[0], "com"); - assert_eq!(dtmi.labels()[1], "example"); - assert_eq!(dtmi.labels()[2], "Thermostat"); - assert_eq!(dtmi.absolute_path, "com:example:Thermostat"); - } - - #[test] - fn bad_create_dtmi_test() { - let mut create_dtmi_result: Option = - create_dtmi("whatever:com:example:Thermostat;1.234567"); - assert!(create_dtmi_result.is_none()); - - create_dtmi_result = create_dtmi("dtmi:com:example:Thermostat;1.2.3"); - assert!(create_dtmi_result.is_none()); - - create_dtmi_result = create_dtmi("dtmi:;1.2"); - assert!(create_dtmi_result.is_none()); - } - - #[test] - fn eq_dtmi_test() { - let first_create_dtmi_result: Option = - create_dtmi("dtmi:com:example:Thermostat;1.234567"); - assert!(first_create_dtmi_result.is_some()); - let first_dtmi = first_create_dtmi_result.unwrap(); - - let second_create_dtmi_result: Option = - create_dtmi("dtmi:com:example:Thermostat;1.234567"); - assert!(second_create_dtmi_result.is_some()); - let second_dtmi = second_create_dtmi_result.unwrap(); - - let third_create_dtmi_result: Option = - create_dtmi("dtmi:com:example:Barometer;2.987"); - assert!(third_create_dtmi_result.is_some()); - let third_dtmi = third_create_dtmi_result.unwrap(); - - assert_eq!(first_dtmi, second_dtmi); - assert!(first_dtmi != third_dtmi); - } -} diff --git a/dtdl-parser/src/entity_info.rs b/dtdl-parser/src/entity_info.rs deleted file mode 100644 index ff21053f..00000000 --- a/dtdl-parser/src/entity_info.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use serde_json::Value; -use std::any::Any; -use std::collections::HashMap; - -use crate::dtmi::Dtmi; -use crate::entity_kind::EntityKind; - -/// A digital twin model consists of building blocks known as entities. -/// EntityInfo is the base trait for all of the digital twin model building blocks. -pub trait EntityInfo: Any { - /// Returns the DTDL version. - fn dtdl_version(&self) -> i32; - - /// Returns the identifier of the DTDL element that corresponds to this object. - fn id(&self) -> &Dtmi; - - /// Returns the kind of Entity, meaning the concrete DTDL type assigned to the corresponding element in the model. - fn entity_kind(&self) -> EntityKind; - - /// Returns the identifier of the parent DTDL element in which this element is defined. - fn child_of(&self) -> &Option; - - /// Returns the identifier of the partition DTDL element in which this element is defined. - fn defined_in(&self) -> &Option; - - // Returns the description for this entity. - fn description(&self) -> &Option; - - // Returns the display name for this entity. - fn display_name(&self) -> &Option; - - /// Returns any undefined properties of the DTDL element that corresponds to this object. - fn undefined_properties(&self) -> &HashMap; - - /// Returns the instance as an Any. - fn as_any(&self) -> &dyn Any; -} diff --git a/dtdl-parser/src/entity_kind.rs b/dtdl-parser/src/entity_kind.rs deleted file mode 100644 index 2ff71022..00000000 --- a/dtdl-parser/src/entity_kind.rs +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use strum_macros::Display; -use strum_macros::EnumIter; -use strum_macros::EnumString; - -/// Indicates the kind of Entity, meaning the concrete DTDL type assigned to the corresponding element in the model. -#[derive(Debug, Copy, Clone, PartialEq, Eq, EnumString, EnumIter, Display)] -pub enum EntityKind { - #[strum(serialize = "dtmi:dtdl:class:Array;2")] - Array, - - #[strum(serialize = "dtmi:dtdl:instance:Schema:boolean;2")] - Boolean, - - #[strum(serialize = "dtmi:dtdl:class:Command;2")] - Command, - - #[strum(serialize = "dtmi:dtdl:class:CommandPayload;2")] - CommandPayload, - - #[strum(serialize = "dtmi:dtdl:class:CommandType;2")] - CommandType, - - #[strum(serialize = "dtmi:dtdl:class:Component;2")] - Component, - - #[strum(serialize = "dtmi:dtdl:instance:Schema:date;2")] - Date, - - #[strum(serialize = "dtmi:dtdl:instance:Schema:dateTime;2")] - DateTime, - - #[strum(serialize = "dtmi:dtdl:instance:Schema:double;2")] - Double, - - #[strum(serialize = "dtmi:dtdl:instance:Schema:duration;2")] - Duration, - - #[strum(serialize = "dtmi:dtdl:class:Enum;2")] - Enum, - - #[strum(serialize = "dtmi:dtdl:class:EnumValue;2")] - EnumValue, - - #[strum(serialize = "dtmi:dtdl:class:Field;2")] - Field, - - #[strum(serialize = "dtmi:dtdl:instance:Schema:float;2")] - Float, - - #[strum(serialize = "dtmi:dtdl:instance:Schema:integer;2")] - Integer, - - #[strum(serialize = "dtmi:dtdl:class:Interface;2")] - Interface, - - #[strum(serialize = "dtmi:dtdl:instance:Schema:long;2")] - Long, - - #[strum(serialize = "dtmi:dtdl:class:Map;2")] - Map, - - #[strum(serialize = "dtmi:dtdl:class:MapKey;2")] - MapKey, - - #[strum(serialize = "dtmi:dtdl:class:MapValue;2")] - MapValue, - - #[strum(serialize = "dtmi:dtdl:class:Object;2")] - Object, - - #[strum(serialize = "dtmi:dtdl:class:Property;2")] - Property, - - #[strum(serialize = "dtmi:dtdl:class:Relationship;2")] - Relationship, - - #[strum(serialize = "dtmi:dtdl:instance:Schema:string;2")] - String, - - #[strum(serialize = "dtmi:dtdl:class:Telemetry;2")] - Telemetry, - - #[strum(serialize = "dtmi:dtdl:instance:Schema:time;2")] - Time, - - #[strum(serialize = "dtmi:dtdl:class:Unit;2")] - Unit, - - #[strum(serialize = "dtmi:dtdl:class:UnitAttribute;2")] - UnitAttribute, - - #[strum(serialize = "dtmi:dtdl:class:CommandRequest;2")] - CommandRequest, - - #[strum(serialize = "dtmi:dtdl:class:CommandResponse;2")] - CommandResponse, - - #[strum(serialize = "dtmi:dtdl:class:LatentType;2")] - LatentType, - - #[strum(serialize = "dtmi:dtdl:class:NamedLatentType;2")] - NamedLatentType, - - #[strum(serialize = "dtmi:dtdl:class:Reference;2")] - Reference, -} diff --git a/dtdl-parser/src/field_info.rs b/dtdl-parser/src/field_info.rs deleted file mode 100644 index a5e628ef..00000000 --- a/dtdl-parser/src/field_info.rs +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::schema_field_info::SchemaFieldInfo; - -/// Specifies a field. -pub trait FieldInfo: SchemaFieldInfo {} diff --git a/dtdl-parser/src/field_info_impl.rs b/dtdl-parser/src/field_info_impl.rs deleted file mode 100644 index c9b4bb75..00000000 --- a/dtdl-parser/src/field_info_impl.rs +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use serde_json::Value; -use std::any::Any; -use std::collections::HashMap; - -use crate::dtmi::Dtmi; -use crate::entity_info::EntityInfo; -use crate::entity_kind::EntityKind; -use crate::field_info::FieldInfo; -use crate::named_entity_info::NamedEntityInfo; -use crate::schema_field_info::SchemaFieldInfo; -use crate::schema_info::SchemaInfo; - -pub struct FieldInfoImpl { - // EntityInfo - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - description: Option, - display_name: Option, - undefined_properties: HashMap, - - // NamedEntityInfo - name: Option, - - // SchemaFieldInfo - schema: Option>, -} - -impl FieldInfoImpl { - /// Returns a new FieldInfoImpl. - /// - /// # Arguments - /// * `dtdl_version` - The DTDL version used to define the field. - /// * `id` - The identifier.. - /// * `child_of` - The identifier of the parent element in which this field is defined. - /// * `defined_in` - The identifier of the partition in which this field is defined. - /// * `name` - The name. - /// * `schema` - The schema. - pub fn new( - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - name: Option, - schema: Option>, - ) -> Self { - Self { - dtdl_version, - id, - child_of, - defined_in, - description: None, - display_name: None, - undefined_properties: HashMap::::new(), - name, - schema, - } - } - - /// Set the display name. - /// - /// # Arguments - /// `display_name` - The new display name. - pub fn set_display_name(&mut self, display_name: Option) { - self.display_name = display_name; - } - - /// Add an undefined property. - /// # Arguments - /// * `key` - The property's name. - /// * `value` - The property's value. - pub fn add_undefined_property(&mut self, key: String, value: Value) { - self.undefined_properties.insert(key, value); - } -} - -impl EntityInfo for FieldInfoImpl { - /// Returns the DTDL version. - fn dtdl_version(&self) -> i32 { - self.dtdl_version - } - - /// Returns the identifier. - fn id(&self) -> &Dtmi { - &self.id - } - - /// Returns the kind of entity. - fn entity_kind(&self) -> EntityKind { - EntityKind::Telemetry - } - - /// Returns the parent's identifier. - fn child_of(&self) -> &Option { - &self.child_of - } - - /// Returns the enclosing partition's identifier. - fn defined_in(&self) -> &Option { - &self.defined_in - } - - // Returns the description for this entity. - fn description(&self) -> &Option { - &self.description - } - - // Returns the display name for this entity. - fn display_name(&self) -> &Option { - &self.display_name - } - - /// Returns all undefined properties. - fn undefined_properties(&self) -> &HashMap { - &self.undefined_properties - } - - /// Returns the instance as an Any. - fn as_any(&self) -> &dyn Any { - self - } -} - -impl NamedEntityInfo for FieldInfoImpl { - /// Returns the name of the field. - fn name(&self) -> &Option { - &self.name - } -} - -impl SchemaFieldInfo for FieldInfoImpl { - /// Returns the schema. - fn schema(&self) -> &Option> { - &self.schema - } -} - -impl FieldInfo for FieldInfoImpl {} - -#[cfg(test)] -mod field_info_impl_tests { - use super::*; - use crate::dtmi::{create_dtmi, Dtmi}; - use crate::model_parser::DTDL_VERSION; - use crate::primitive_schema_info_impl::PrimitiveSchemaInfoImpl; - use serde_json; - - #[test] - fn new_field_info_impl_test() -> Result<(), String> { - let id_result: Option = create_dtmi("dtmi:com:example:Field;1.0"); - assert!(id_result.is_some()); - let id = id_result.unwrap(); - - let child_of_result: Option = create_dtmi("dtmi:com:example:Cabin;1.0"); - assert!(child_of_result.is_some()); - let child_of = child_of_result.unwrap(); - - let defined_in_result: Option = create_dtmi("dtmi:com:example;1.0"); - assert!(defined_in_result.is_some()); - let defined_in = defined_in_result.unwrap(); - - let first_propery_value: Value = serde_json::from_str("{\"first\": \"this\"}").unwrap(); - let second_propery_value: Value = serde_json::from_str("{\"second\": \"that\"}").unwrap(); - - let schema_info_id: Option = create_dtmi("dtmi:dtdl:class:String;2"); - assert!(schema_info_id.is_some()); - - let boxed_schema_info = Box::new(PrimitiveSchemaInfoImpl::new( - DTDL_VERSION, - schema_info_id.unwrap(), - None, - None, - EntityKind::String, - )); - - let mut field_info = FieldInfoImpl::new( - DTDL_VERSION, - id.clone(), - Some(child_of.clone()), - Some(defined_in.clone()), - Some(String::from("one")), - Some(boxed_schema_info), - ); - field_info.add_undefined_property(String::from("first"), first_propery_value.clone()); - field_info.add_undefined_property(String::from("second"), second_propery_value.clone()); - - assert_eq!(field_info.dtdl_version(), 2); - assert_eq!(field_info.id(), &id); - assert!(field_info.child_of().is_some()); - assert_eq!(field_info.child_of().clone().unwrap(), child_of); - assert!(field_info.defined_in().is_some()); - assert_eq!(field_info.defined_in().clone().unwrap(), defined_in); - assert_eq!(field_info.entity_kind(), EntityKind::Telemetry); - assert_eq!(field_info.undefined_properties().len(), 2); - assert_eq!( - field_info.undefined_properties().get("first").unwrap().clone(), - first_propery_value - ); - assert_eq!( - field_info.undefined_properties().get("second").unwrap().clone(), - second_propery_value - ); - - match field_info.name() { - Some(name) => assert_eq!(name, "one"), - None => return Err(String::from("name has not been set")), - } - - match field_info.schema() { - Some(schema) => assert_eq!(schema.entity_kind(), EntityKind::String), - None => return Err(String::from("schema has not been set")), - } - - Ok(()) - } -} diff --git a/dtdl-parser/src/interface_info.rs b/dtdl-parser/src/interface_info.rs deleted file mode 100644 index 7b63776b..00000000 --- a/dtdl-parser/src/interface_info.rs +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::entity_info::EntityInfo; - -/// An interface specifies a collection of Commands, Components, Properties, Relationships and Telemetries. -pub trait InterfaceInfo: EntityInfo {} diff --git a/dtdl-parser/src/interface_info_impl.rs b/dtdl-parser/src/interface_info_impl.rs deleted file mode 100644 index ec64adca..00000000 --- a/dtdl-parser/src/interface_info_impl.rs +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use serde_json::Value; -use std::any::Any; -use std::collections::HashMap; - -use crate::dtmi::Dtmi; -use crate::entity_info::EntityInfo; -use crate::entity_kind::EntityKind; -use crate::interface_info::InterfaceInfo; - -#[derive(Clone)] -pub struct InterfaceInfoImpl { - // EntitytInfo - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - description: Option, - display_name: Option, - undefined_properties: HashMap, -} - -impl InterfaceInfoImpl { - /// Returns a new InterfaceInfoImpl. - /// - /// # Arguments - /// * `dtdl_version` - The DTDL version used to define the interface. - /// * `id` - The identifier. - /// * `child_of` - The identifier of the parent element in which this interface is defined. - /// * `defined_in` - The identifier of the partition in which this interface is defined. - pub fn new( - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - ) -> Self { - Self { - dtdl_version, - id, - child_of, - defined_in, - description: None, - display_name: None, - undefined_properties: HashMap::::new(), - } - } - - /// Add an undefined property. - /// # Arguments - /// * `key` - The property's name. - /// * `value` - The property's value. - pub fn add_undefined_property(&mut self, key: String, value: Value) { - self.undefined_properties.insert(key, value); - } -} - -impl EntityInfo for InterfaceInfoImpl { - /// Returns the DTDL version. - fn dtdl_version(&self) -> i32 { - self.dtdl_version - } - - /// Returns the identifier. - fn id(&self) -> &Dtmi { - &self.id - } - - /// Returns the kind of entity. - fn entity_kind(&self) -> EntityKind { - EntityKind::Interface - } - - /// Returns the parent's identifier. - fn child_of(&self) -> &Option { - &self.child_of - } - - /// Returns the enclosing partition's identifier. - fn defined_in(&self) -> &Option { - &self.defined_in - } - - // Returns the description for this entity. - fn description(&self) -> &Option { - &self.description - } - - // Returns the display name for this entity. - fn display_name(&self) -> &Option { - &self.display_name - } - - /// Returns all undefined properties. - fn undefined_properties(&self) -> &HashMap { - &self.undefined_properties - } - - /// Returns the instance as an Any. - fn as_any(&self) -> &dyn Any { - self - } -} - -impl InterfaceInfo for InterfaceInfoImpl {} - -#[cfg(test)] -mod interface_info_impl_tests { - use super::*; - use crate::dtmi::{create_dtmi, Dtmi}; - use crate::model_parser::DTDL_VERSION; - use serde_json; - - #[test] - fn new_interface_info_impl_test() { - let id_result: Option = create_dtmi("dtmi:com:example:my_interface;1.0"); - assert!(id_result.is_some()); - let id = id_result.unwrap(); - - let child_of_result: Option = create_dtmi("dtmi:com:example:vehicle;1.0"); - assert!(child_of_result.is_some()); - let child_of = child_of_result.unwrap(); - - let defined_in_result: Option = create_dtmi("dtmi:com:example;1.0"); - assert!(defined_in_result.is_some()); - let defined_in = defined_in_result.unwrap(); - - let first_propery_value: Value = serde_json::from_str("{\"first\": \"this\"}").unwrap(); - let second_propery_value: Value = serde_json::from_str("{\"second\": \"that\"}").unwrap(); - - let mut interface_info = InterfaceInfoImpl::new( - DTDL_VERSION, - id.clone(), - Some(child_of.clone()), - Some(defined_in.clone()), - ); - interface_info.add_undefined_property(String::from("first"), first_propery_value.clone()); - interface_info.add_undefined_property(String::from("second"), second_propery_value.clone()); - - assert_eq!(interface_info.dtdl_version(), 2); - assert_eq!(interface_info.id(), &id); - assert!(interface_info.child_of().is_some()); - assert_eq!(interface_info.child_of().clone().unwrap(), child_of); - assert!(interface_info.defined_in().is_some()); - assert_eq!(interface_info.defined_in().clone().unwrap(), defined_in); - assert_eq!(interface_info.entity_kind(), EntityKind::Interface); - assert_eq!(interface_info.undefined_properties().len(), 2); - assert_eq!( - interface_info.undefined_properties().get("first").unwrap().clone(), - first_propery_value - ); - assert_eq!( - interface_info.undefined_properties().get("second").unwrap().clone(), - second_propery_value - ); - } -} diff --git a/dtdl-parser/src/lib.rs b/dtdl-parser/src/lib.rs deleted file mode 100644 index 61a1ca45..00000000 --- a/dtdl-parser/src/lib.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -#[macro_use] -extern crate lazy_static; - -extern crate json_ld; - -pub mod command_info; -pub mod command_info_impl; -pub mod command_payload_info; -pub mod command_payload_info_impl; -pub mod complex_schema_info; -pub mod component_info; -pub mod component_info_impl; -pub mod content_info; -pub mod dtmi; -pub mod entity_info; -pub mod entity_kind; -pub mod field_info; -pub mod field_info_impl; -pub mod interface_info; -pub mod interface_info_impl; -pub mod model_dict; -pub mod model_parser; -pub mod named_entity_info; -pub mod object_info; -pub mod object_info_impl; -pub mod primitive_schema_info; -pub mod primitive_schema_info_impl; -pub mod primitive_schema_kinds; -pub mod property_info; -pub mod property_info_impl; -pub mod relationship_info; -pub mod relationship_info_impl; -pub mod schema_field_info; -pub mod schema_info; -pub mod telemetry_info; -pub mod telemetry_info_impl; diff --git a/dtdl-parser/src/model_dict.rs b/dtdl-parser/src/model_dict.rs deleted file mode 100644 index 182bf0f1..00000000 --- a/dtdl-parser/src/model_dict.rs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::dtmi::Dtmi; -use crate::entity_info::EntityInfo; - -use std::collections::HashMap; - -pub type ModelDict = HashMap>; diff --git a/dtdl-parser/src/model_parser.rs b/dtdl-parser/src/model_parser.rs deleted file mode 100644 index 6b8216ef..00000000 --- a/dtdl-parser/src/model_parser.rs +++ /dev/null @@ -1,1175 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use futures::executor::block_on; -use json_ld::{context, Document, NoLoader, Node, Object}; -use log::warn; -use serde_json::{Map, Value}; -use std::collections::HashMap; -use std::env; -use std::fs; -use std::path::Path; -use std::str::FromStr; -use strum::IntoEnumIterator; - -use crate::command_info_impl::CommandInfoImpl; -use crate::command_payload_info::CommandPayloadInfo; -use crate::command_payload_info_impl::CommandPayloadInfoImpl; -use crate::component_info_impl::ComponentInfoImpl; -use crate::dtmi::{create_dtmi, Dtmi}; -use crate::entity_kind::EntityKind; -use crate::field_info::FieldInfo; -use crate::field_info_impl::FieldInfoImpl; -use crate::interface_info::InterfaceInfo; -use crate::interface_info_impl::InterfaceInfoImpl; -use crate::json_ld::util::AsJson; -use crate::model_dict::ModelDict; -use crate::object_info_impl::ObjectInfoImpl; -use crate::primitive_schema_info_impl::PrimitiveSchemaInfoImpl; -use crate::primitive_schema_kinds::is_primitive_schema_kind; -use crate::property_info_impl::PropertyInfoImpl; -use crate::relationship_info_impl::RelationshipInfoImpl; -use crate::schema_info::SchemaInfo; -use crate::telemetry_info_impl::TelemetryInfoImpl; - -/// The DTDL Version that the parser supports. -pub const DTDL_VERSION: i32 = 2; - -/// Instances of the ModelParser class parse models written in the DTDL language. -/// This class can be used to determine: whether one or more DTDL models are valid, -/// to identify specific modeling errors, and to enable inspection of model contents. -pub struct ModelParser {} - -impl Default for ModelParser { - fn default() -> Self { - Self::new() - } -} - -impl ModelParser { - /// The DTDL-path environment variable name. - pub const DTDL_PATH: &str = "DTDL_PATH"; - - /// Returns a new ModelParser instance. - pub fn new() -> Self { - Self {} - } - - /// Parse a list of JSON texts and return the resulting model dictionary. - /// - /// # Arguments - /// * `json_texts` - A list of JSON texts. - pub fn parse(&mut self, json_texts: &Vec) -> Result { - let mut model_dict: ModelDict = ModelDict::new(); - - self.add_primitive_schemas_to_model_dict(&mut model_dict)?; - - // Add the entries to the model dictionary for the primitive entity kinds. - for entity_kind in EntityKind::iter() { - if is_primitive_schema_kind(entity_kind) { - let schema_info_id: Option = create_dtmi(&entity_kind.to_string()); - if schema_info_id.is_none() { - return Err(format!( - "Cannot form a valid schema id for primitive entity kind '{entity_kind}." - )); - } - - let boxed_entity_info = Box::new(PrimitiveSchemaInfoImpl::new( - DTDL_VERSION, - schema_info_id.clone().unwrap(), - None, - None, - entity_kind, - )); - model_dict.insert(schema_info_id.clone().unwrap(), boxed_entity_info); - } - } - - for json_text in json_texts { - let mut doc: Value = match serde_json::from_str(json_text) { - Ok(json) => json, - Err(error) => { - return Err(format!("Failed to parse one of the JSON texts due to: {error}")) - } - }; - - self.preprocess(&mut doc)?; - - let mut loader = NoLoader::::new(); - let dtdl_doc = - block_on(doc.expand::, _>(&mut loader)).map_err(|error| { - format!("Failed to expand one of the JSON texts due to: {error:?}") - })?; - - for item in dtdl_doc.iter() { - let object: &Object = item; - if let Object::Node(node) = object { - self.parse_node(node, &None, &mut model_dict)?; - } - } - } - - Ok(model_dict) - } - - /// Add the entries to the model dictionary for the primitive schemas. - /// - /// # Arguments - /// * `model_dict` - The model dictionary. - fn add_primitive_schemas_to_model_dict( - &mut self, - model_dict: &mut ModelDict, - ) -> Result<(), String> { - for entity_kind in EntityKind::iter() { - if is_primitive_schema_kind(entity_kind) { - let schema_info_id: Option = create_dtmi(&entity_kind.to_string()); - if schema_info_id.is_none() { - return Err(format!( - "Cannot form a valid schema id for primitive schema {entity_kind}." - )); - } - - let boxed_entity_info = Box::new(PrimitiveSchemaInfoImpl::new( - DTDL_VERSION, - schema_info_id.clone().unwrap(), - None, - None, - entity_kind, - )); - model_dict.insert(schema_info_id.clone().unwrap(), boxed_entity_info); - } - } - - Ok(()) - } - - /// Retrieve a JSON-LD context as a JSON object from the location specified in the filepath. - /// - /// # Arguments - /// * `filepath` - The file path where the context is located. - fn retrieve_context(&mut self, filepath: &Path) -> Result { - let contents: String = match fs::read_to_string(filepath) { - Ok(data) => data, - Err(error) => { - return Err(format!( - "Unable to read the context located at {} due to: {:?}", - filepath.display(), - error - )) - } - }; - - let doc: Value = match serde_json::from_str(&contents) { - Ok(json) => json, - Err(error) => { - return Err(format!( - "Unable to parse the context located at {} due to: {:?}", - filepath.display(), - error - )) - } - }; - - Ok(doc) - } - - /// Replace a name reference for a context in a JSON object with its respective JSON value. - /// - /// # Arguments - /// * `obj` - The JSON object represented as a map of names to JSON objects. - /// * `context_name` - The name of the context that we want to replace. - /// * 'context_value` - The JSON object that we will replace it with. - #[allow(clippy::needless_range_loop)] - fn replace_context_inline_in_object( - &mut self, - obj: &mut Map, - context_name: &str, - context_value: &Value, - ) -> Result<(), String> { - let existing_context_value_option = obj.get_mut("@context"); - if let Some(existing_context_value) = existing_context_value_option { - if let Value::String(s) = existing_context_value { - if s == context_name { - obj.remove("@context"); - obj.insert(String::from("@context"), context_value.clone()); - } - } else if let Value::Array(a) = existing_context_value { - for i in 0..a.len() { - if let Value::String(_) = &a[i] { - if a[i] == context_name { - a[i] = context_value.clone(); - break; - } - } - } - } else if let Value::Object(_o) = existing_context_value { - // ignore - this one does not have an IRI associated with it. - } else { - return Err(format!("Unexpected context value '{existing_context_value:?}'")); - } - } - Ok(()) - } - - /// Replace a name reference for a context in a JSON-LD document with its respective JSON value. - /// - /// # Arguments - /// * `doc` - The JSON document. - /// * `context_name` - The name of the context that we want to replace. - /// * 'context_value` - The JSON object that we will replace it with. - fn replace_context_inline_in_doc( - &mut self, - doc: &mut Value, - context_name: &str, - context_value: &Value, - ) -> Result<(), String> { - match doc { - Value::Array(array) => { - for v in array.iter_mut() { - self.replace_context_inline_in_doc(v, context_name, context_value)?; - } - } - Value::Object(object) => { - self.replace_context_inline_in_object(object, context_name, context_value)?; - } - _ => warn!("An unexpected json value was encountered"), - } - Ok(()) - } - - /// Preprocess a JSON-LD document, so that supported dtmi contexts will have their names replaced by their respective JSON. - /// - /// # Arguments - /// * `doc` - The JSON-LD document to preprocess. - /// - /// # Examples of supported context formats: - /// - /// "@context": "https://json-ld.org/contexts/person.json" - /// - /// "@context": [ - /// "https://json-ld.org/contexts/person.json", - /// "https://json-ld.org/contexts/place.json", - /// {"title": "http://purl.org/dc/terms/title"} - /// ] - fn preprocess(&mut self, doc: &mut Value) -> Result<(), String> { - let dtdl_2_context_path_string = Self::find_full_path("v2/context/DTDL.v2.context.json")?; - let dtdl_2_context_path_string_unwrapped = dtdl_2_context_path_string; - let dtdl_2_context_path = Path::new(&dtdl_2_context_path_string_unwrapped); - let dtdl_2_context_value = self.retrieve_context(dtdl_2_context_path)?; - self.replace_context_inline_in_doc(doc, "dtmi:dtdl:context;2", &dtdl_2_context_value)?; - - Ok(()) - } - - /// Get a property value from a node by name. - /// - /// # Arguments - /// * `node` - The node that contains the property. - /// * `property_name` - The name of the property. - fn get_property_value( - &self, - node: &Node, - property_name: &str, - ) -> Result, String> { - for (the_property, the_objects) in node.properties() { - if the_property == property_name { - if the_objects.len() == 1 { - match the_objects[0].as_str() { - Some(v) => return Ok(Some(String::from(v))), - None => { - return Err(String::from( - "get_property_value was unable to convert the value to a str", - )) - } - } - } else { - return Err(String::from( - "get_property_value does not contain the expected number of objects", - )); - } - } - } - - Ok(None) - } - - /// Get the schema info for a primary or existing schema. Both are represented by a schema name that could represent either case. - /// This function will determine which one it is and return the corresponding schema info. - /// - /// # Arguments - /// * `node` - The node that contains the schema's name. - /// * `model_dict` - The model dictionary, containing the schema infos that have already been captured. - /// * `parent_id` - The parent id. - fn get_primary_or_existing_schema( - &self, - node: &Node, - model_dict: &mut ModelDict, - parent_id: &Option, - ) -> Result, String> { - let string_option: Option<&str> = node.as_str(); - if let Some(schema_name) = string_option { - let entity_kind_option: Option = match EntityKind::from_str(schema_name) { - Ok(v) => Some(v), - Err(_) => None, - }; - - if let Some(entity_kind) = entity_kind_option { - if is_primitive_schema_kind(entity_kind) { - let id: Option = self.generate_id(parent_id, "test"); - if id.is_none() { - return Err(String::from( - "we were not able to generate an id for the schema", - )); - } - - Ok(Box::new(PrimitiveSchemaInfoImpl::new( - DTDL_VERSION, - id.unwrap(), - parent_id.clone(), - None, - entity_kind, - ))) - } else { - Err(format!("expected a primitive schema, found {entity_kind}")) - } - } else { - self.retrieve_schema_info_from_model_dict(schema_name, model_dict) - } - } else { - Err(String::from("get_schema encountered an unknown entity kind value")) - } - } - - /// Get an object schema info from a node. - /// - /// # Arguments - /// * `node` - The node that contains the object schema's specification. - /// * `model_dict` - The model dictionary, containing the schema infos that have already been captured. - /// * `parent_id` - The parent id. - fn get_object_schema( - &self, - node: &Node, - model_dict: &mut ModelDict, - parent_id: &Option, - ) -> Result, String> { - let mut fields: Vec> = Vec::new(); - - for (the_property, the_objects) in node.properties() { - if the_property == "dtmi:dtdl:property:fields;2" { - for i in 0..the_objects.len() { - if let Object::Node(node) = &*the_objects[i] { - let mut name_option: Option = None; - let mut display_name_option: Option = None; - let mut schema: Option> = None; - for (the_property, the_objects) in node.properties() { - if the_property == "dtmi:dtdl:property:displayName;2" - && the_objects.len() == 1 - { - if let Object::Value(value) = &*the_objects[0] { - display_name_option = value.as_str().map(String::from) - } - } else if the_property == "dtmi:dtdl:property:schema;2" - && the_objects.len() == 1 - { - if let Object::Node(node) = &*the_objects[0] { - if node.properties().is_empty() { - schema = Some(self.get_primary_or_existing_schema( - node, model_dict, parent_id, - )?); - } else { - schema = Some( - self.get_complex_schema(node, model_dict, parent_id)?, - ); - } - } - } else if the_property == "dtmi:dtdl:property:name;2" - && the_objects.len() == 1 - { - if let Object::Value(value) = &*the_objects[0] { - name_option = value.as_str().map(String::from) - } - } - } - if name_option.is_some() { - let id: Option = - self.generate_id(parent_id, &name_option.clone().unwrap()); - if id.is_none() { - return Err(String::from( - "We were not able to generate an id for the schema.", - )); - } - - let mut field_info = FieldInfoImpl::new( - DTDL_VERSION, - id.unwrap(), - parent_id.clone(), - None, - name_option, - schema, - ); - - field_info.set_display_name(display_name_option); - - fields.push(Box::new(field_info)); - } - } - } - } - } - - let id: Option = self.generate_id(parent_id, "test"); - if id.is_none() { - return Err(String::from("We were not able to generate an id for the schema.")); - } - - Ok(Box::new(ObjectInfoImpl::new( - DTDL_VERSION, - id.unwrap(), - parent_id.clone(), - None, - Some(fields), - ))) - } - - /// Get a complex schema info from a node. - /// - /// # Arguments - /// * `node` - The node that contains the complex schema's specification. - /// * `model_dict` - The model dictionary, containing the schema infos that have already been captured. - /// * `parent_id` - The parent id. - fn get_complex_schema( - &self, - node: &Node, - model_dict: &mut ModelDict, - parent_id: &Option, - ) -> Result, String> { - let mut entity_kind_option: Option = None; - for node_type in node.types() { - let entity_kind_result = EntityKind::from_str(node_type.as_str()); - if let Ok(entity_kind) = entity_kind_result { - entity_kind_option = Some(entity_kind); - break; - } - } - - if entity_kind_option.is_none() { - return Err(String::from("Complex schema has no associated type. It must have one.")); - } - - let entity_kind = entity_kind_option.unwrap(); - - if entity_kind == EntityKind::Object { - self.get_object_schema(node, model_dict, parent_id) - } else { - Err(format!("Unsupported complex object: {entity_kind:?}.")) - } - } - - /// Get a schema info from a node. - /// - /// # Arguments - /// * `node` - The node that contains the schema's specification. - /// * `model_dict` - The model dictionary, containing the schema infos that have already been captured. - /// * `parent_id` - The parent id. - fn get_schema( - &self, - node: &Node, - model_dict: &mut ModelDict, - parent_id: &Option, - ) -> Result, String> { - for (the_property, the_objects) in node.properties() { - if the_property == "dtmi:dtdl:property:schema;2" { - if the_objects.len() == 1 { - if let Object::Node(node) = &*the_objects[0] { - if node.properties().is_empty() { - return self - .get_primary_or_existing_schema(node, model_dict, parent_id); - } else { - return self.get_complex_schema(node, model_dict, parent_id); - } - } else { - return Err(String::from( - "The schema property's associated object should be a node. It is not.", - )); - } - } else { - return Err(format!( - "The schema property should only have 1 assoicated object. It has {}.", - the_objects.len() - )); - } - } - } - - Err(String::from("A schema property was not found.")) - } - - /// Get the payload. - /// - /// # Arguments - /// * `node` - The node that contains the payload's specification. - /// * `model_dict` - The model dictionary, containing the schema infos that have already been captured. - /// * `property_name` - The property name associated with the payload. - /// * `parent_id` - The parent id. - fn get_payload( - &self, - node: &Node, - model_dict: &mut ModelDict, - property_name: &str, - parent_id: &Option, - ) -> Result>, String> { - for (the_property, the_objects) in node.properties() { - if the_property == property_name { - if let Object::Node(node) = &*the_objects[0] { - // name - optional - let name = self.get_property_value(node, "dtmi:dtdl:property:name;2")?; - - let mut id: Option = None; - if node.id().is_some() { - id = create_dtmi(node.id().unwrap().as_str()); - } - if id.is_none() { - if name.is_none() { - return Err(String::from( - "We cannot generate an id for the payload when we do not have a name.", - )); - } - id = self.generate_id(parent_id, &name.clone().unwrap()); - if id.is_none() { - return Err(String::from( - "We were unable to generate an id for the payload.", - )); - } - } - - // displayName - required - let _display_name = - self.get_property_value(node, "dtmi:dtdl:property:displayName;2")?; - - // description - required - let _description = - self.get_property_value(node, "dtmi:dtdl:property:description;2")?; - - // schema - required - let boxed_schema_info: Box = - self.get_schema(node, model_dict, &id)?; - - return Ok(Some(Box::new(CommandPayloadInfoImpl::new( - DTDL_VERSION, - id.unwrap(), - parent_id.clone(), - None, - name, - Some(boxed_schema_info), - )))); - } else { - return Err(String::from("get_payload encountered an unknown object")); - } - } - } - - Ok(None) - } - - /// Gather the undefined propeties from a node. - /// - /// # Arguments - /// * `node` - The node to gather the undefined properties from. - /// * `undefined_properties` - The resulting gathered undefined properties. - fn gather_undefined_properties( - node: &Node, - undefined_properties: &mut HashMap, - ) { - for (the_property, the_objects) in node.properties() { - if the_objects.len() == 1 { - match &*the_objects[0] { - Object::Value(value) => { - let j = value.clone().as_json(); - undefined_properties.insert(the_property.to_string(), j); - } - Object::Node(n) => { - Self::gather_undefined_properties(n, undefined_properties); - } - Object::List(_list) => { - warn!("gather_undefined_properties encountered a list"); - } - } - } - } - } - - /// Genrate an id from the associated parent id and the associated property name. - /// - /// # Arguments - /// * `parent_id` - The associated parent id. - /// * `name` - The associated property name. - fn generate_id(&self, parent_id: &Option, name: &str) -> Option { - let generated_id_value = format!("{}:{}", parent_id.clone().unwrap().versionless(), name); - create_dtmi(&generated_id_value) - } - - /// Retrieve a schema info from a dictionary. - /// - /// # Arguments - /// * `schema` - The id (as a string) for the schema info. - /// * `model_dict` - The model dictionary to search. - fn retrieve_schema_info_from_model_dict( - &self, - schema: &str, - model_dict: &mut ModelDict, - ) -> Result, String> { - let primitive_schema_info_id: Option = create_dtmi(schema); - if primitive_schema_info_id.is_none() { - return Err(String::from("Primitive schema cannot form a valid schema id.")); - } - let primitive_schema_info_model_entry = - model_dict.get(&primitive_schema_info_id.clone().unwrap()); - if primitive_schema_info_model_entry.is_none() { - return Err(format!( - "We were not able to find the primitive schema entry for id '{}'.", - primitive_schema_info_id.unwrap() - )); - } - let boxed_primitive_schema_info_ref_result = primitive_schema_info_model_entry - .unwrap() - .as_any() - .downcast_ref::(); - let boxed_schema_info: Box = match boxed_primitive_schema_info_ref_result { - Some(boxed_primitive_schema_info_ref) => { - Box::new((*boxed_primitive_schema_info_ref).clone()) - } - None => return Err(String::from("Was not a primitive schema info")), - }; - - Ok(boxed_schema_info) - } - - /// Retrieve an interface info from a model dictionary. - /// - /// # Arguments - /// * `schema` - The id (as a string) for the interface info. - /// * `model_dict` - The model dictionary to search. - fn retrieve_interface_info_from_model_dict( - &mut self, - schema: &str, - model_dict: &mut ModelDict, - ) -> Result, String> { - let interface_info_id: Option = create_dtmi(schema); - if interface_info_id.is_none() { - return Err(String::from("Schema cannot form a valid schema id.")); - } - let interface_info_model_entry = model_dict.get(&interface_info_id.clone().unwrap()); - if interface_info_model_entry.is_none() { - return Err(format!( - "We were not able to find the interface entry for id '{}'.", - interface_info_id.unwrap() - )); - } - let boxed_interface_schema_info_ref_result = - interface_info_model_entry.unwrap().as_any().downcast_ref::(); - let boxed_interface_info: Box = - match boxed_interface_schema_info_ref_result { - Some(boxed_interface_schema_info_ref) => { - Box::new((*boxed_interface_schema_info_ref).clone()) - } - None => return Err(String::from("Was not an interface info")), - }; - - Ok(boxed_interface_info) - } - - /// Parse a node. - /// - /// # Arguments - /// * `node` - The node to parse. - /// * `model_dict` - The model dictionary to add the content to. - fn parse_node( - &mut self, - node: &Node, - parent_id: &Option, - model_dict: &mut ModelDict, - ) -> Result<(), String> { - let mut entity_kind_option: Option = None; - for node_type in node.types() { - let entity_kind_result = EntityKind::from_str(node_type.as_str()); - if let Ok(entity_kind) = entity_kind_result { - entity_kind_option = Some(entity_kind); - break; - } - } - - if entity_kind_option.is_none() { - return Err(String::from("Warning: No entity kind found amongst the node's types")); - } - - match entity_kind_option.unwrap() { - EntityKind::Interface => self.parse_interface(node, parent_id, model_dict)?, - EntityKind::Telemetry => self.parse_telemetry(node, parent_id, model_dict)?, - EntityKind::Property => self.parse_property(node, parent_id, model_dict)?, - EntityKind::Command => self.parse_command(node, parent_id, model_dict)?, - EntityKind::Relationship => self.parse_relationship(node, parent_id, model_dict)?, - EntityKind::Component => self.parse_component(node, parent_id, model_dict)?, - _ => return Err(String::from("Warning: Unexepcted entity kind found ")), - } - - Ok(()) - } - - /// Parse an interface. - /// - /// # Arguments - /// * `node` - The node that represents an interface. - /// * `parent_id` - The interface's parent id. - /// * `model_dict` - The model dictionary to add the content to. - fn parse_interface( - &mut self, - node: &Node, - parent_id: &Option, - model_dict: &mut ModelDict, - ) -> Result<(), String> { - // @id - required - let mut id: Option = None; - if node.id().is_some() { - id = create_dtmi(node.id().unwrap().as_str()); - } - if id.is_none() { - return Err(format!( - "Interface does not have a valid id '{}'", - node.id().unwrap().as_str() - )); - } - - // contents - optional - for (the_property, the_objects) in node.properties() { - if the_property != "dtmi:dtdl:property:contents;2" { - continue; - } - for the_object in the_objects { - let object: &Object = the_object; - if let Object::Node(node) = object { - self.parse_node(node, &id, model_dict)?; - } - } - } - - // Add the interface to the model dictionary. - let entity_info = Box::new(InterfaceInfoImpl::new( - DTDL_VERSION, - id.clone().unwrap(), - parent_id.clone(), - None, - )); - model_dict.insert(id.clone().unwrap(), entity_info); - - Ok(()) - } - - /// Parse a telemetry. - /// - /// # Arguments - /// * `node` - The node that represents a telemetry. - /// * `parent_id` - The telemetry's parent id. - /// * `model_dict` - The model dictionary to add the content to. - fn parse_telemetry( - &mut self, - node: &Node, - parent_id: &Option, - model_dict: &mut ModelDict, - ) -> Result<(), String> { - // name - optional - let name = self.get_property_value(node, "dtmi:dtdl:property:name;2")?; - - // schema - required - let boxed_schema_info: Box = - self.get_schema(node, model_dict, parent_id)?; - - let mut id: Option = None; - if node.id().is_some() { - id = create_dtmi(node.id().unwrap().as_str()); - } - if id.is_none() { - if name.is_none() { - return Err(String::from( - "We cannot generate an id for the telemtry when we do not have a name.", - )); - } - id = self.generate_id(parent_id, &name.clone().unwrap()); - if id.is_none() { - return Err(String::from("We were not able to generate an id for the telemetry.")); - } - } - - let mut undefined_property_values = HashMap::::new(); - Self::gather_undefined_properties(node, &mut undefined_property_values); - - let mut telemetry_info = TelemetryInfoImpl::new( - DTDL_VERSION, - id.clone().unwrap(), - parent_id.clone(), - None, - name, - Some(boxed_schema_info), - ); - - for (key, value) in undefined_property_values { - telemetry_info.add_undefined_property(key, value); - } - - model_dict.insert(id.unwrap(), Box::new(telemetry_info)); - - Ok(()) - } - - /// Parse a property. - /// - /// # Arguments - /// * `node` - The node that represents a property. - /// * `parent_id` - The property's parent id. - /// * `model_dict` - The model dictionary to add the content to. - fn parse_property( - &mut self, - node: &Node, - parent_id: &Option, - model_dict: &mut ModelDict, - ) -> Result<(), String> { - // name - optional - let name = self.get_property_value(node, "dtmi:dtdl:property:name;2")?; - - // schema - required - let boxed_schema_info: Box = - self.get_schema(node, model_dict, parent_id)?; - - let mut id: Option = None; - if node.id().is_some() { - id = create_dtmi(node.id().unwrap().as_str()); - } - if id.is_none() { - if name.is_none() { - return Err(String::from( - "We cannot generate an id for the property when we do not have a name.", - )); - } - id = self.generate_id(parent_id, &name.clone().unwrap()); - if id.is_none() { - return Err(String::from("We were not able to generate an id for the property.")); - } - } - - let mut undefined_property_values = HashMap::::new(); - Self::gather_undefined_properties(node, &mut undefined_property_values); - - let mut property_info = PropertyInfoImpl::new( - DTDL_VERSION, - id.clone().unwrap(), - parent_id.clone(), - None, - name, - Some(boxed_schema_info), - false, - ); - - for (key, value) in undefined_property_values { - property_info.add_undefined_property(key, value); - } - - model_dict.insert(id.unwrap(), Box::new(property_info)); - - Ok(()) - } - - /// Parse a command. - /// - /// # Arguments - /// * `node` - The node that represents a command. - /// * `parent_id` - The command's parent id. - /// * `model_dict` - The model dictionary to add the content to. - fn parse_command( - &mut self, - node: &Node, - parent_id: &Option, - model_dict: &mut ModelDict, - ) -> Result<(), String> { - // name - optional - let name = self.get_property_value(node, "dtmi:dtdl:property:name;2")?; - - let mut id: Option = None; - if node.id().is_some() { - id = create_dtmi(node.id().unwrap().as_str()); - } - if id.is_none() { - if name.is_none() { - return Err(String::from( - "We cannot generate an id for the command when we do not have a name.", - )); - } - id = self.generate_id(parent_id, &name.clone().unwrap()); - if id.is_none() { - return Err(String::from("We were not able to generate an id for the command.")); - } - } - - let request_payload: Option> = - self.get_payload(node, model_dict, "dtmi:dtdl:property:request;2", &id)?; - let response_payload: Option> = - self.get_payload(node, model_dict, "dtmi:dtdl:property:response;2", &id)?; - - let mut undefined_property_values = HashMap::::new(); - Self::gather_undefined_properties(node, &mut undefined_property_values); - - let mut command_info = CommandInfoImpl::new( - DTDL_VERSION, - id.clone().unwrap(), - parent_id.clone(), - None, - name, - request_payload, - response_payload, - ); - - for (key, value) in undefined_property_values { - command_info.add_undefined_property(key, value); - } - - model_dict.insert(id.clone().unwrap(), Box::new(command_info)); - - Ok(()) - } - - /// Parse a relationship. - /// - /// # Arguments - /// * `node` - The node that represents a relationship. - /// * `parent_id` - The relationship's parent id. - /// * `model_dict` - The model dictionary to add the content to. - fn parse_relationship( - &mut self, - node: &Node, - parent_id: &Option, - model_dict: &mut ModelDict, - ) -> Result<(), String> { - // name - optional - let name = self.get_property_value(node, "dtmi:dtdl:property:name;2")?; - - let mut id: Option = None; - if node.id().is_some() { - id = create_dtmi(node.id().unwrap().as_str()); - } - if id.is_none() { - if name.is_none() { - return Err(String::from( - "We cannot generate an id for the relationship when we do not have a name.", - )); - } - id = self.generate_id(parent_id, &name.clone().unwrap()); - if id.is_none() { - return Err(String::from( - "We were not able to generate an id for the relationship.", - )); - } - } - - let entity_info = Box::new(RelationshipInfoImpl::new( - DTDL_VERSION, - id.clone().unwrap(), - parent_id.clone(), - None, - name, - None, - false, - )); - model_dict.insert(id.unwrap(), entity_info); - - Ok(()) - } - - // Parse a component. - /// - /// # Arguments - /// * `node` - The node that represents a component. - /// * `parent_id` - The component's parent id. - /// * `model_dict` - The model dictionary to add the content to. - fn parse_component( - &mut self, - node: &Node, - parent_id: &Option, - model_dict: &mut ModelDict, - ) -> Result<(), String> { - // name - optional - let name = self.get_property_value(node, "dtmi:dtdl:property:name;2")?; - - // schema - required (note: here the schema property represents an interface) - let schema = self.get_property_value(node, "dtmi:dtdl:property:schema;2")?; - if schema.is_none() { - return Err(String::from("Component does not have a schema property.")); - } - let boxed_interface_info: Box = - self.retrieve_interface_info_from_model_dict(&schema.unwrap(), model_dict)?; - - let mut id: Option = None; - if node.id().is_some() { - id = create_dtmi(node.id().unwrap().as_str()); - } - if id.is_none() { - if name.is_none() { - return Err(String::from( - "We cannot generate an id for the component when we do not have a name.", - )); - } - id = self.generate_id(parent_id, &name.clone().unwrap()); - if id.is_none() { - return Err(String::from("We were not able to generate an id for the component.")); - } - } - - let entity_info = Box::new(ComponentInfoImpl::new( - DTDL_VERSION, - id.clone().unwrap(), - parent_id.clone(), - None, - name, - Some(boxed_interface_info), - )); - model_dict.insert(id.unwrap(), entity_info); - - Ok(()) - } - - /// Find the full path given a relative path and a preset DTDL_PATH environment variable (containing a semicolon-separated list of DTDL directories). - /// - /// # Arguments - /// `relative_path` - The relative path. - pub fn find_full_path(relative_path: &str) -> Result { - match env::var(Self::DTDL_PATH) { - Ok(paths) => { - let split = paths.split(';'); - let vec: Vec<&str> = split.collect(); - for path in vec { - let full_path = Path::new(path).join(relative_path); - if full_path.exists() { - return Ok(full_path.to_str().unwrap().to_string()); - } - } - } - Err(_) => { - return Err(String::from( - "Unable to get the environment variable DTDL_PATH. Please set it.", - )) - } - } - Err(String::from("Unable to resolve the full path")) - } -} - -#[cfg(test)] -mod model_parser_tests { - use super::*; - use log::trace; - use std::fs; - use std::path::Path; - use std::vec::Vec; - - /// The DTDL-path environment variable name. - const CARGO_MANIFEST_DIR: &str = "CARGO_MANIFEST_DIR"; - - /// Retrieve the contents of the DTDL from the specified file path. - /// - /// # Arguments: - /// `file_path` - The file path where the DTDL is located. - fn retrieve_dtdl(file_path: &str) -> Result { - let path = Path::new(file_path); - let read_result = fs::read_to_string(path); - match read_result { - Ok(contents) => Ok(contents), - Err(error) => Err(format!("Unable to retrieve the DTDL due to: {error}")), - } - } - - /// Get the repository's directory. - fn get_repo_dir() -> Option { - // CARGO_MANIFEST_DIR - The directory containing the manifest of your package. - let cargo_manifest_dir_result = env::var(CARGO_MANIFEST_DIR); - if let Ok(cargo_manifest_dir) = cargo_manifest_dir_result { - let cargo_manifest_dir_path = Path::new(&cargo_manifest_dir); - let parent_result = cargo_manifest_dir_path.parent(); - if let Some(parent) = parent_result { - parent.to_str().map(String::from) - } else { - None - } - } else { - None - } - } - - /// Set the DTDL_PATH environment, so that the tests can use it. - fn set_dtdl_path() { - let repo_dir_result = get_repo_dir(); - if let Some(repo_dir) = repo_dir_result { - let value = format!( - "{repo_dir}/external/opendigitaltwins-dtdl/DTDL;{repo_dir}/external/iot-plugandplay-models;{repo_dir}/dtdl-parser/dtdl;{repo_dir}/digital-twin-model/dtdl" - ); - env::set_var(ModelParser::DTDL_PATH, &value); - trace!("{}={value}", ModelParser::DTDL_PATH); - } else { - warn!( - "Unable to set {}, as repo directory could not be determined.", - ModelParser::DTDL_PATH - ); - } - } - - #[test] - fn validation_test() { - set_dtdl_path(); - - let mut json_texts = Vec::::new(); - - let device_information_full_path_result = - ModelParser::find_full_path("dtmi/azure/devicemanagement/deviceinformation-1.json"); - assert!(device_information_full_path_result.is_ok()); - let device_information_contents_result = - retrieve_dtdl(&device_information_full_path_result.unwrap()); - assert!(device_information_contents_result.is_ok()); - json_texts.push(device_information_contents_result.unwrap()); - - let thermostat_full_path_result = ModelParser::find_full_path("v2/samples/Thermostat.json"); - assert!(thermostat_full_path_result.is_ok()); - let thermostat_contents_result = retrieve_dtdl(&thermostat_full_path_result.unwrap()); - assert!(thermostat_contents_result.is_ok()); - json_texts.push(thermostat_contents_result.unwrap()); - - let temp_controller_full_path_result = - ModelParser::find_full_path("v2/samples/TemperatureController.json"); - assert!(temp_controller_full_path_result.is_ok()); - let temp_controller_contents_result = - retrieve_dtdl(&temp_controller_full_path_result.unwrap()); - assert!(temp_controller_contents_result.is_ok()); - json_texts.push(temp_controller_contents_result.unwrap()); - - let mut parser = ModelParser::new(); - let model_dict_result = parser.parse(&json_texts); - assert!( - model_dict_result.is_ok(), - "parse failed due to: {}", - model_dict_result.err().unwrap() - ); - let model_dict = model_dict_result.unwrap(); - assert_eq!( - model_dict.len(), - 31, - "expected length was 31, actual length is {}", - model_dict.len() - ); - } - - #[test] - fn find_full_path_test() { - set_dtdl_path(); - - let find_full_path_result = ModelParser::find_full_path("v3/spec/sdv/hvac.json"); - assert!(find_full_path_result.is_ok()); - let full_path = find_full_path_result.unwrap(); - assert!(full_path.ends_with("/v3/spec/sdv/hvac.json")); - } -} diff --git a/dtdl-parser/src/named_entity_info.rs b/dtdl-parser/src/named_entity_info.rs deleted file mode 100644 index 29d4c273..00000000 --- a/dtdl-parser/src/named_entity_info.rs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::entity_info::EntityInfo; - -/// An abstract trait that represents named entites. -pub trait NamedEntityInfo: EntityInfo { - /// Returns the name. - fn name(&self) -> &Option; -} diff --git a/dtdl-parser/src/object_info.rs b/dtdl-parser/src/object_info.rs deleted file mode 100644 index 26910bf8..00000000 --- a/dtdl-parser/src/object_info.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::complex_schema_info::ComplexSchemaInfo; -use crate::field_info::FieldInfo; - -/// An object specifies a value compromised of named fields. -pub trait ObjectInfo: ComplexSchemaInfo { - /// Returns the fields. - fn fields(&self) -> &Option>>; -} diff --git a/dtdl-parser/src/object_info_impl.rs b/dtdl-parser/src/object_info_impl.rs deleted file mode 100644 index f2fa6ec5..00000000 --- a/dtdl-parser/src/object_info_impl.rs +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use serde_json::Value; -use std::any::Any; -use std::collections::HashMap; - -use crate::complex_schema_info::ComplexSchemaInfo; -use crate::dtmi::Dtmi; -use crate::entity_info::EntityInfo; -use crate::entity_kind::EntityKind; -use crate::field_info::FieldInfo; -use crate::object_info::ObjectInfo; -use crate::schema_info::SchemaInfo; - -pub struct ObjectInfoImpl { - // EntitytInfo - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - description: Option, - display_name: Option, - undefined_properties: HashMap, - - // ObjectInfo - fields: Option>>, -} - -impl ObjectInfoImpl { - /// Returns a new ObjectInfoImpl. - /// - /// # Arguments - /// * `dtdl_version` - The DTDL version of used to define the object. - /// * `id` - The identifier. - /// * `child_of` - The identifier of the parent element in which this object is defined. - /// * `defined_in` - The identifier of the partition in which this object is defined. - /// * `fields` - The fields. - pub fn new( - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - fields: Option>>, - ) -> Self { - Self { - dtdl_version, - id, - child_of, - defined_in, - description: None, - display_name: None, - undefined_properties: HashMap::::new(), - fields, - } - } - - /// Add an undefined property. - /// # Arguments - /// * `key` - The property's name. - /// * `value` - The property's value. - pub fn add_undefined_property(&mut self, key: String, value: Value) { - self.undefined_properties.insert(key, value); - } -} - -impl EntityInfo for ObjectInfoImpl { - /// Returns the DTDL version. - fn dtdl_version(&self) -> i32 { - self.dtdl_version - } - - /// Returns the identifier. - fn id(&self) -> &Dtmi { - &self.id - } - - /// Returns the kind of entity. - fn entity_kind(&self) -> EntityKind { - EntityKind::Object - } - - /// Returns the parent's identifier. - fn child_of(&self) -> &Option { - &self.child_of - } - - /// Returns the enclosing partition's identifier. - fn defined_in(&self) -> &Option { - &self.defined_in - } - - // Returns the description for this entity. - fn description(&self) -> &Option { - &self.description - } - - // Returns the display name for this entity. - fn display_name(&self) -> &Option { - &self.display_name - } - - /// Returns all undefined properties. - fn undefined_properties(&self) -> &HashMap { - &self.undefined_properties - } - - /// Returns the instance as an Any. - fn as_any(&self) -> &dyn Any { - self - } -} - -impl SchemaInfo for ObjectInfoImpl {} - -impl ComplexSchemaInfo for ObjectInfoImpl {} - -impl ObjectInfo for ObjectInfoImpl { - // Returns the fields. - fn fields(&self) -> &Option>> { - &self.fields - } -} - -#[cfg(test)] -mod object_info_impl_tests { - use super::*; - use crate::dtmi::{create_dtmi, Dtmi}; - use crate::model_parser::DTDL_VERSION; - use serde_json; - - #[test] - fn new_object_info_impl_test() -> Result<(), String> { - let id_result: Option = create_dtmi("dtmi:com:example:Object;1.0"); - assert!(id_result.is_some()); - let id = id_result.unwrap(); - - let child_of_result: Option = create_dtmi("dtmi:com:example:Cabin;1.0"); - assert!(child_of_result.is_some()); - let child_of = child_of_result.unwrap(); - - let defined_in_result: Option = create_dtmi("dtmi:com:example;1.0"); - assert!(defined_in_result.is_some()); - let defined_in = defined_in_result.unwrap(); - - let first_propery_value: Value = serde_json::from_str("{\"first\": \"this\"}").unwrap(); - let second_propery_value: Value = serde_json::from_str("{\"second\": \"that\"}").unwrap(); - - let fields = Vec::new(); - - let mut object_info = ObjectInfoImpl::new( - DTDL_VERSION, - id.clone(), - Some(child_of.clone()), - Some(defined_in.clone()), - Some(fields), - ); - object_info.add_undefined_property(String::from("first"), first_propery_value.clone()); - object_info.add_undefined_property(String::from("second"), second_propery_value.clone()); - - assert_eq!(object_info.dtdl_version(), 2); - assert_eq!(object_info.id(), &id); - assert!(object_info.child_of().is_some()); - assert_eq!(object_info.child_of().clone().unwrap(), child_of); - assert!(object_info.defined_in().is_some()); - assert_eq!(object_info.defined_in().clone().unwrap(), defined_in); - assert_eq!(object_info.entity_kind(), EntityKind::Object); - assert_eq!(object_info.undefined_properties().len(), 2); - assert_eq!( - object_info.undefined_properties().get("first").unwrap().clone(), - first_propery_value - ); - assert_eq!( - object_info.undefined_properties().get("second").unwrap().clone(), - second_propery_value - ); - - match object_info.fields() { - Some(fields) => assert_eq!(fields.len(), 0), - None => return Err(String::from("fields has not been set")), - } - - Ok(()) - } -} diff --git a/dtdl-parser/src/primitive_schema_info.rs b/dtdl-parser/src/primitive_schema_info.rs deleted file mode 100644 index 57f3ea04..00000000 --- a/dtdl-parser/src/primitive_schema_info.rs +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::schema_info::SchemaInfo; - -/// A primitive schema is the trait that represents all primitive schemas, like boolean, integer, string and time. -pub trait PrimitiveSchemaInfo: SchemaInfo {} diff --git a/dtdl-parser/src/primitive_schema_info_impl.rs b/dtdl-parser/src/primitive_schema_info_impl.rs deleted file mode 100644 index 6fae4032..00000000 --- a/dtdl-parser/src/primitive_schema_info_impl.rs +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use serde_json::Value; -use std::any::Any; -use std::collections::HashMap; - -use crate::dtmi::Dtmi; -use crate::entity_info::EntityInfo; -use crate::entity_kind::EntityKind; -use crate::primitive_schema_info::PrimitiveSchemaInfo; -use crate::schema_info::SchemaInfo; - -#[derive(Clone, PartialEq, Eq)] -pub struct PrimitiveSchemaInfoImpl { - // EntitytInfo - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - entity_kind: EntityKind, - description: Option, - display_name: Option, - undefined_properties: HashMap, -} - -impl PrimitiveSchemaInfoImpl { - /// Returns a new PrimitiveSchemaInfoImpl. - /// - /// # Arguments - /// * `dtdl_version` - The DTDL version used to define the primitive schema. - /// * `id` - The identifier. - /// * `child_of` - The identifier of the parent element in which this primitive schema is defined. - /// * `defined_in` - The identifier of the partition in which this relationship is defined. - /// * `entity_kind` - The entity kind. - pub fn new( - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - entity_kind: EntityKind, - ) -> Self { - Self { - dtdl_version, - id, - child_of, - defined_in, - entity_kind, - description: None, - display_name: None, - undefined_properties: HashMap::::new(), - } - } - - /// Add an undefined property. - /// # Arguments - /// * `key` - The property's name. - /// * `value` - The property's value. - pub fn add_undefined_property(&mut self, key: String, value: Value) { - self.undefined_properties.insert(key, value); - } -} - -impl EntityInfo for PrimitiveSchemaInfoImpl { - /// Returns the DTDL version. - fn dtdl_version(&self) -> i32 { - self.dtdl_version - } - - /// Returns the identifier. - fn id(&self) -> &Dtmi { - &self.id - } - - /// Returns the kind of entity. - fn entity_kind(&self) -> EntityKind { - self.entity_kind - } - - /// Returns the parent identifier. - fn child_of(&self) -> &Option { - &self.child_of - } - - /// Returns the enclosing partition's identifier. - fn defined_in(&self) -> &Option { - &self.defined_in - } - - // Returns the description for this entity. - fn description(&self) -> &Option { - &self.description - } - - // Returns the display name for this entity. - fn display_name(&self) -> &Option { - &self.display_name - } - - /// Returns all undefined properties. - fn undefined_properties(&self) -> &HashMap { - &self.undefined_properties - } - - /// Returns the instance as an Any. - fn as_any(&self) -> &dyn Any { - self - } -} - -impl SchemaInfo for PrimitiveSchemaInfoImpl {} - -impl PrimitiveSchemaInfo for PrimitiveSchemaInfoImpl {} - -#[cfg(test)] -mod primitive_schema_info_impl_tests { - use super::*; - use crate::dtmi::{create_dtmi, Dtmi}; - use crate::model_parser::DTDL_VERSION; - use serde_json; - - #[test] - fn new_primitive_schema_info_impl_test() { - let id_result: Option = create_dtmi("dtmi:com:example:String;1.0"); - assert!(id_result.is_some()); - let id = id_result.unwrap(); - - let first_propery_value: Value = serde_json::from_str("{\"first\": \"this\"}").unwrap(); - let second_propery_value: Value = serde_json::from_str("{\"second\": \"that\"}").unwrap(); - - let mut primitive_schema_info = - PrimitiveSchemaInfoImpl::new(DTDL_VERSION, id.clone(), None, None, EntityKind::String); - primitive_schema_info - .add_undefined_property(String::from("first"), first_propery_value.clone()); - primitive_schema_info - .add_undefined_property(String::from("second"), second_propery_value.clone()); - - assert_eq!(primitive_schema_info.dtdl_version(), 2); - assert_eq!(primitive_schema_info.id(), &id); - assert!(primitive_schema_info.child_of().is_none()); - assert!(primitive_schema_info.defined_in().is_none()); - assert!(primitive_schema_info.entity_kind() == EntityKind::String); - assert_eq!(primitive_schema_info.undefined_properties().len(), 2); - assert_eq!( - primitive_schema_info.undefined_properties().get("first").unwrap().clone(), - first_propery_value - ); - assert_eq!( - primitive_schema_info.undefined_properties().get("second").unwrap().clone(), - second_propery_value - ); - } -} diff --git a/dtdl-parser/src/primitive_schema_kinds.rs b/dtdl-parser/src/primitive_schema_kinds.rs deleted file mode 100644 index b7eea51c..00000000 --- a/dtdl-parser/src/primitive_schema_kinds.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::entity_kind::EntityKind; - -/// Does the entity kind represent a primitive schema? -/// -/// # Arguments -/// * `entity_kind` - The entity kind. -pub fn is_primitive_schema_kind(entity_kind: EntityKind) -> bool { - entity_kind == EntityKind::Boolean - || entity_kind == EntityKind::Date - || entity_kind == EntityKind::DateTime - || entity_kind == EntityKind::Double - || entity_kind == EntityKind::Duration - || entity_kind == EntityKind::Float - || entity_kind == EntityKind::Integer - || entity_kind == EntityKind::Long - || entity_kind == EntityKind::String - || entity_kind == EntityKind::Time -} diff --git a/dtdl-parser/src/property_info.rs b/dtdl-parser/src/property_info.rs deleted file mode 100644 index 0a77d1c7..00000000 --- a/dtdl-parser/src/property_info.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::content_info::ContentInfo; -use crate::schema_info::SchemaInfo; - -/// A property specifies a value that may be read and in some cases also written. -pub trait PropertyInfo: ContentInfo { - /// Returns the schema. - fn schema(&self) -> &Option>; - - /// Returns whether the property is writable. - fn writable(&self) -> bool; -} diff --git a/dtdl-parser/src/property_info_impl.rs b/dtdl-parser/src/property_info_impl.rs deleted file mode 100644 index 26140866..00000000 --- a/dtdl-parser/src/property_info_impl.rs +++ /dev/null @@ -1,224 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use serde_json::Value; -use std::any::Any; -use std::collections::HashMap; - -use crate::content_info::ContentInfo; -use crate::dtmi::Dtmi; -use crate::entity_info::EntityInfo; -use crate::entity_kind::EntityKind; -use crate::named_entity_info::NamedEntityInfo; -use crate::property_info::PropertyInfo; -use crate::schema_info::SchemaInfo; - -pub struct PropertyInfoImpl { - // EntitytInfo - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - description: Option, - display_name: Option, - undefined_properties: HashMap, - - // NamedEntityInfo - name: Option, - - // PropertyInfo - schema: Option>, - writable: bool, -} - -impl PropertyInfoImpl { - /// Returns a new PropertyInfoImpl. - /// - /// # Arguments - /// * `dtdl_version` - The DTDL version used to define the property. - /// * `id` - The identifier. - /// * `child_of` - The identifier of the parent element in which this property is defined. - /// * `defined_in` - The identifier of the partition in which this property is defined. - /// * `schema` - The schema. - /// * `writable` - Is the property writable? - pub fn new( - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - name: Option, - schema: Option>, - writable: bool, - ) -> Self { - Self { - dtdl_version, - id, - child_of, - defined_in, - description: None, - display_name: None, - undefined_properties: HashMap::::new(), - name, - schema, - writable, - } - } - - /// Add an undefined property. - /// # Arguments - /// * `key` - The property's name. - /// * `value` - The property's value. - pub fn add_undefined_property(&mut self, key: String, value: Value) { - self.undefined_properties.insert(key, value); - } -} - -impl EntityInfo for PropertyInfoImpl { - /// Returns the DTDL version. - fn dtdl_version(&self) -> i32 { - self.dtdl_version - } - - /// Returns the identifier. - fn id(&self) -> &Dtmi { - &self.id - } - - /// Returns the kind of entity/ - fn entity_kind(&self) -> EntityKind { - EntityKind::Property - } - - /// Returns the parent's identifier. - fn child_of(&self) -> &Option { - &self.child_of - } - - /// Returns the enclosing partition's identifier. - fn defined_in(&self) -> &Option { - &self.defined_in - } - - // Returns the description for this entity. - fn description(&self) -> &Option { - &self.description - } - - // Returns the display name for this entity. - fn display_name(&self) -> &Option { - &self.display_name - } - - /// Returns all undefined properties. - fn undefined_properties(&self) -> &HashMap { - &self.undefined_properties - } - - /// Returns the instance as an Any. - fn as_any(&self) -> &dyn Any { - self - } -} - -impl NamedEntityInfo for PropertyInfoImpl { - /// Returns the name of the property. - fn name(&self) -> &Option { - &self.name - } -} - -impl ContentInfo for PropertyInfoImpl {} - -impl PropertyInfo for PropertyInfoImpl { - /// Returns the schema. - fn schema(&self) -> &Option> { - &self.schema - } - - /// Returns whether the property is writable. - fn writable(&self) -> bool { - self.writable - } -} - -#[cfg(test)] -mod property_info_impl_tests { - use super::*; - use crate::dtmi::{create_dtmi, Dtmi}; - use crate::model_parser::DTDL_VERSION; - use crate::primitive_schema_info_impl::PrimitiveSchemaInfoImpl; - use serde_json; - - #[test] - fn new_property_info_impl_test() -> Result<(), String> { - let id_result: Option = create_dtmi("dtmi:com:example:Thermostat;1.0"); - assert!(id_result.is_some()); - let id = id_result.unwrap(); - - let child_of_result: Option = create_dtmi("dtmi:com:example:Cabin;1.0"); - assert!(child_of_result.is_some()); - let child_of = child_of_result.unwrap(); - - let defined_in_result: Option = create_dtmi("dtmi:com:example;1.0"); - assert!(defined_in_result.is_some()); - let defined_in = defined_in_result.unwrap(); - - let first_propery_value: Value = serde_json::from_str("{\"first\": \"this\"}").unwrap(); - let second_propery_value: Value = serde_json::from_str("{\"second\": \"that\"}").unwrap(); - - let schema_info_id: Option = create_dtmi("dtmi:dtdl:class:String;2"); - assert!(schema_info_id.is_some()); - - let boxed_schema_info = Box::new(PrimitiveSchemaInfoImpl::new( - DTDL_VERSION, - schema_info_id.unwrap(), - None, - None, - EntityKind::String, - )); - - let mut property_info = PropertyInfoImpl::new( - DTDL_VERSION, - id.clone(), - Some(child_of.clone()), - Some(defined_in.clone()), - Some(String::from("one")), - Some(boxed_schema_info), - true, - ); - property_info.add_undefined_property(String::from("first"), first_propery_value.clone()); - property_info.add_undefined_property(String::from("second"), second_propery_value.clone()); - - assert_eq!(property_info.dtdl_version(), 2); - assert_eq!(property_info.id(), &id); - assert!(property_info.child_of().is_some()); - assert_eq!(property_info.child_of().clone().unwrap(), child_of); - assert!(property_info.defined_in().is_some()); - assert_eq!(property_info.defined_in().clone().unwrap(), defined_in); - assert_eq!(property_info.entity_kind(), EntityKind::Property); - assert_eq!(property_info.undefined_properties().len(), 2); - assert_eq!( - property_info.undefined_properties().get("first").unwrap().clone(), - first_propery_value - ); - assert_eq!( - property_info.undefined_properties().get("second").unwrap().clone(), - second_propery_value - ); - - match property_info.name() { - Some(name) => assert_eq!(name, "one"), - None => return Err(String::from("name has not been set")), - } - - match property_info.schema() { - Some(schema) => assert_eq!(schema.entity_kind(), EntityKind::String), - None => return Err(String::from("schema has not been set")), - } - - assert!(property_info.writable()); - - Ok(()) - } -} diff --git a/dtdl-parser/src/relationship_info.rs b/dtdl-parser/src/relationship_info.rs deleted file mode 100644 index a5e53b53..00000000 --- a/dtdl-parser/src/relationship_info.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::content_info::ContentInfo; -use crate::schema_info::SchemaInfo; - -/// A relationshp specifies an assoication with an interface. It allows graphs to be built. -pub trait RelationshipInfo: ContentInfo { - /// Returns the schema. - fn schema(&self) -> &Option>; - - /// Returns whether the property is writable. - fn writable(&self) -> bool; -} diff --git a/dtdl-parser/src/relationship_info_impl.rs b/dtdl-parser/src/relationship_info_impl.rs deleted file mode 100644 index caf4f4bc..00000000 --- a/dtdl-parser/src/relationship_info_impl.rs +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use serde_json::Value; -use std::any::Any; -use std::collections::HashMap; - -use crate::content_info::ContentInfo; -use crate::dtmi::Dtmi; -use crate::entity_info::EntityInfo; -use crate::entity_kind::EntityKind; -use crate::named_entity_info::NamedEntityInfo; -use crate::relationship_info::RelationshipInfo; -use crate::schema_info::SchemaInfo; - -pub struct RelationshipInfoImpl { - // EntitytInfo - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - description: Option, - display_name: Option, - undefined_properties: HashMap, - - // NamedEntityInfo - name: Option, - - // RelationshipInfo - schema: Option>, - writable: bool, -} - -impl RelationshipInfoImpl { - /// Returns a new RelationshipInfoImpl. - /// - /// # Arguments - /// * `dtdl_version` - The DTDL version used to define the relationship. - /// * `id` - The identifier. - /// * `child_of` - The identifier of the parent element in which this relationship is defined. - /// * `defined_in` - The identifier of the partition in which this relationship is defined. - /// * `name` - The name. - /// * `schema` - The schema. - /// * `writable` - Is the relationship writable? - pub fn new( - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - name: Option, - schema: Option>, - writable: bool, - ) -> Self { - Self { - dtdl_version, - id, - child_of, - defined_in, - description: None, - display_name: None, - undefined_properties: HashMap::::new(), - name, - schema, - writable, - } - } - - /// Add an undefined property. - /// # Arguments - /// * `key` - The property's name. - /// * `value` - The property's value. - pub fn add_undefined_property(&mut self, key: String, value: Value) { - self.undefined_properties.insert(key, value); - } -} - -impl EntityInfo for RelationshipInfoImpl { - /// Returns the DTDL version. - fn dtdl_version(&self) -> i32 { - self.dtdl_version - } - - /// Returns the identifier. - fn id(&self) -> &Dtmi { - &self.id - } - - /// Returns the kind of entity. - fn entity_kind(&self) -> EntityKind { - EntityKind::Property - } - - /// Returns the parent's identifier. - fn child_of(&self) -> &Option { - &self.child_of - } - - /// Returns the enclosing partition's identifier. - fn defined_in(&self) -> &Option { - &self.defined_in - } - - // Returns the description for this entity. - fn description(&self) -> &Option { - &self.description - } - - // Returns the display name for this entity. - fn display_name(&self) -> &Option { - &self.display_name - } - - /// Returns all undefined properties. - fn undefined_properties(&self) -> &HashMap { - &self.undefined_properties - } - - /// Returns the instance as an Any. - fn as_any(&self) -> &dyn Any { - self - } -} - -impl NamedEntityInfo for RelationshipInfoImpl { - /// Returns the name. - fn name(&self) -> &Option { - &self.name - } -} - -impl ContentInfo for RelationshipInfoImpl {} - -impl RelationshipInfo for RelationshipInfoImpl { - /// Returns the schema. - fn schema(&self) -> &Option> { - &self.schema - } - - /// Returns whether the relationship is writable. - fn writable(&self) -> bool { - self.writable - } -} - -#[cfg(test)] -mod relationship_info_impl_tests { - use super::*; - use crate::dtmi::{create_dtmi, Dtmi}; - use crate::model_parser::DTDL_VERSION; - use crate::primitive_schema_info_impl::PrimitiveSchemaInfoImpl; - use serde_json; - - #[test] - fn new_relationship_info_impl_test() -> Result<(), String> { - let id_result: Option = create_dtmi("dtmi:com:example:my_relationship;1.0"); - assert!(id_result.is_some()); - let id = id_result.unwrap(); - - let child_of_result: Option = create_dtmi("dtmi:com:example:vehicle;1.0"); - assert!(child_of_result.is_some()); - let child_of = child_of_result.unwrap(); - - let defined_in_result: Option = create_dtmi("dtmi:com:example;1.0"); - assert!(defined_in_result.is_some()); - let defined_in = defined_in_result.unwrap(); - - let first_propery_value: Value = serde_json::from_str("{\"first\": \"this\"}").unwrap(); - let second_propery_value: Value = serde_json::from_str("{\"second\": \"that\"}").unwrap(); - - let schema_info_id: Option = create_dtmi("dtmi:dtdl:class:String;2"); - assert!(schema_info_id.is_some()); - - let boxed_schema_info = Box::new(PrimitiveSchemaInfoImpl::new( - DTDL_VERSION, - schema_info_id.unwrap(), - None, - None, - EntityKind::String, - )); - - let mut relationship_info = RelationshipInfoImpl::new( - DTDL_VERSION, - id.clone(), - Some(child_of.clone()), - Some(defined_in.clone()), - Some(String::from("one")), - Some(boxed_schema_info), - false, - ); - relationship_info - .add_undefined_property(String::from("first"), first_propery_value.clone()); - relationship_info - .add_undefined_property(String::from("second"), second_propery_value.clone()); - - assert_eq!(relationship_info.dtdl_version(), 2); - assert_eq!(relationship_info.id(), &id); - assert!(relationship_info.child_of().is_some()); - assert_eq!(relationship_info.child_of().clone().unwrap(), child_of); - assert!(relationship_info.defined_in().is_some()); - assert_eq!(relationship_info.defined_in().clone().unwrap(), defined_in); - assert_eq!(relationship_info.entity_kind(), EntityKind::Property); - assert_eq!(relationship_info.undefined_properties().len(), 2); - assert_eq!( - relationship_info.undefined_properties().get("first").unwrap().clone(), - first_propery_value - ); - assert_eq!( - relationship_info.undefined_properties().get("second").unwrap().clone(), - second_propery_value - ); - - match relationship_info.name() { - Some(name) => assert_eq!(name, "one"), - None => return Err(String::from("name has not been set")), - } - - Ok(()) - } -} diff --git a/dtdl-parser/src/schema_field_info.rs b/dtdl-parser/src/schema_field_info.rs deleted file mode 100644 index 119a2df1..00000000 --- a/dtdl-parser/src/schema_field_info.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::named_entity_info::NamedEntityInfo; -use crate::schema_info::SchemaInfo; - -/// An abstract trait that represents an entity that has a schema field. -pub trait SchemaFieldInfo: NamedEntityInfo { - /// Returns the schema. - fn schema(&self) -> &Option>; -} diff --git a/dtdl-parser/src/schema_info.rs b/dtdl-parser/src/schema_info.rs deleted file mode 100644 index 12c65115..00000000 --- a/dtdl-parser/src/schema_info.rs +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::entity_info::EntityInfo; - -/// A schema is the base trait for all primitive and complex schemas. -pub trait SchemaInfo: EntityInfo {} diff --git a/dtdl-parser/src/telemetry_info.rs b/dtdl-parser/src/telemetry_info.rs deleted file mode 100644 index 9f8553dc..00000000 --- a/dtdl-parser/src/telemetry_info.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use crate::content_info::ContentInfo; -use crate::schema_info::SchemaInfo; - -/// A telemetry specifies data that is emitted as a stream. -pub trait TelemetryInfo: ContentInfo { - /// Returns the schema. - fn schema(&self) -> &Option>; -} diff --git a/dtdl-parser/src/telemetry_info_impl.rs b/dtdl-parser/src/telemetry_info_impl.rs deleted file mode 100644 index 5f4c7f49..00000000 --- a/dtdl-parser/src/telemetry_info_impl.rs +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// SPDX-License-Identifier: MIT - -use serde_json::Value; -use std::any::Any; -use std::collections::HashMap; - -use crate::content_info::ContentInfo; -use crate::dtmi::Dtmi; -use crate::entity_info::EntityInfo; -use crate::entity_kind::EntityKind; -use crate::named_entity_info::NamedEntityInfo; -use crate::schema_info::SchemaInfo; -use crate::telemetry_info::TelemetryInfo; - -pub struct TelemetryInfoImpl { - // EntityInfo - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - description: Option, - display_name: Option, - undefined_properties: HashMap, - - // NamedEntityInfo - name: Option, - - // TelemetryInfo - schema: Option>, -} - -impl TelemetryInfoImpl { - /// Returns a new TelemetryInfoImpl. - /// - /// # Arguments - /// * `dtdl_version` - The DTDL version used to define the telemetry. - /// * `id` - The identifier. - /// * `child_of` - The identifier of the parent element in which this telemetry is defined. - /// * `defined_in` - The identifier of the partition in which this telemetry is defined. - /// * `name` - The name. - /// * `schema` - The schema. - pub fn new( - dtdl_version: i32, - id: Dtmi, - child_of: Option, - defined_in: Option, - name: Option, - schema: Option>, - ) -> Self { - Self { - dtdl_version, - id, - child_of, - defined_in, - description: None, - display_name: None, - undefined_properties: HashMap::::new(), - name, - schema, - } - } - - /// Add an undefined property. - /// # Arguments - /// * `key` - The property's name. - /// * `value` - The property's value. - pub fn add_undefined_property(&mut self, key: String, value: Value) { - self.undefined_properties.insert(key, value); - } -} - -impl EntityInfo for TelemetryInfoImpl { - // Returns the DTDL version. - fn dtdl_version(&self) -> i32 { - self.dtdl_version - } - - /// Returns the identifier. - fn id(&self) -> &Dtmi { - &self.id - } - - /// Returns the kind of entity. - fn entity_kind(&self) -> EntityKind { - EntityKind::Telemetry - } - - /// Returns the parent's identifier. - fn child_of(&self) -> &Option { - &self.child_of - } - - /// Returns the enclosing partition's identifier. - fn defined_in(&self) -> &Option { - &self.defined_in - } - - // Returns the description for this entity. - fn description(&self) -> &Option { - &self.description - } - - // Returns the display name for this entity. - fn display_name(&self) -> &Option { - &self.display_name - } - - /// Returns all undefined properties. - fn undefined_properties(&self) -> &HashMap { - &self.undefined_properties - } - - /// Returns the instance as an Any. - fn as_any(&self) -> &dyn Any { - self - } -} - -impl NamedEntityInfo for TelemetryInfoImpl { - /// Returns the name. - fn name(&self) -> &Option { - &self.name - } -} - -impl ContentInfo for TelemetryInfoImpl {} - -impl TelemetryInfo for TelemetryInfoImpl { - /// Returns the schema. - fn schema(&self) -> &Option> { - &self.schema - } -} - -#[cfg(test)] -mod telemetry_info_impl_tests { - use super::*; - use crate::dtmi::{create_dtmi, Dtmi}; - use crate::model_parser::DTDL_VERSION; - use crate::primitive_schema_info_impl::PrimitiveSchemaInfoImpl; - use serde_json; - - #[test] - fn new_telemetry_info_impl_test() -> Result<(), String> { - let id_result: Option = create_dtmi("dtmi:com:example:Thermostat;1.0"); - assert!(id_result.is_some()); - let id = id_result.unwrap(); - - let child_of_result: Option = create_dtmi("dtmi:com:example:Cabin;1.0"); - assert!(child_of_result.is_some()); - let child_of = child_of_result.unwrap(); - - let defined_in_result: Option = create_dtmi("dtmi:com:example;1.0"); - assert!(defined_in_result.is_some()); - let defined_in = defined_in_result.unwrap(); - - let first_propery_value: Value = serde_json::from_str("{\"first\": \"this\"}").unwrap(); - let second_propery_value: Value = serde_json::from_str("{\"second\": \"that\"}").unwrap(); - - let schema_info_id: Option = create_dtmi("dtmi:dtdl:class:String;2"); - assert!(schema_info_id.is_some()); - - let boxed_schema_info = Box::new(PrimitiveSchemaInfoImpl::new( - DTDL_VERSION, - schema_info_id.unwrap(), - None, - None, - EntityKind::String, - )); - - let mut telemetry_info = TelemetryInfoImpl::new( - DTDL_VERSION, - id.clone(), - Some(child_of.clone()), - Some(defined_in.clone()), - Some(String::from("one")), - Some(boxed_schema_info), - ); - telemetry_info.add_undefined_property(String::from("first"), first_propery_value.clone()); - telemetry_info.add_undefined_property(String::from("second"), second_propery_value.clone()); - - assert_eq!(telemetry_info.dtdl_version(), 2); - assert_eq!(telemetry_info.id(), &id); - assert!(telemetry_info.child_of().is_some()); - assert_eq!(telemetry_info.child_of().clone().unwrap(), child_of); - assert!(telemetry_info.defined_in().is_some()); - assert_eq!(telemetry_info.defined_in().clone().unwrap(), defined_in); - assert_eq!(telemetry_info.entity_kind(), EntityKind::Telemetry); - assert_eq!(telemetry_info.undefined_properties().len(), 2); - assert_eq!( - telemetry_info.undefined_properties().get("first").unwrap().clone(), - first_propery_value - ); - assert_eq!( - telemetry_info.undefined_properties().get("second").unwrap().clone(), - second_propery_value - ); - - match telemetry_info.name() { - Some(name) => assert_eq!(name, "one"), - None => return Err(String::from("name has not been set")), - } - - match telemetry_info.schema() { - Some(schema) => assert_eq!(schema.entity_kind(), EntityKind::String), - None => return Err(String::from("schema has not been set")), - } - - Ok(()) - } -} diff --git a/dtdl-tools/Cargo.toml b/dtdl-tools/Cargo.toml new file mode 100644 index 00000000..75435e1f --- /dev/null +++ b/dtdl-tools/Cargo.toml @@ -0,0 +1,9 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT license. +# SPDX-License-Identifier: MIT + +[package] +name = "dtdl-tools" +version = "0.1.0" +edition = "2021" +license = "MIT" diff --git a/dtdl-tools/build.rs b/dtdl-tools/build.rs new file mode 100644 index 00000000..c7ece626 --- /dev/null +++ b/dtdl-tools/build.rs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// SPDX-License-Identifier: MIT + +use std::process::Command; + +// This build script builds all the .NET projects in this digital_twins_connector folder. +// Running 'cargo build' will build the .NET projects and the Rust crates. +fn main() { + const DOTNET_COMMAND: &str = "dotnet"; + const DOTNET_BUILD_ARG: &str = "build"; + + const CSPROJ_PATHS: &[&str] = &[ + "src/dtdl-validator/dtdl-validator.csproj", + ]; + + for csproj in CSPROJ_PATHS { + let output = Command::new(DOTNET_COMMAND) + .arg(DOTNET_BUILD_ARG) + .arg(csproj) + .output() + .unwrap(); + + if !output.status.success() { + panic!("Failed to run due to {output:?}"); + } + } +} diff --git a/dtdl-tools/src/dtdl-validator/Directory.Build.props b/dtdl-tools/src/dtdl-validator/Directory.Build.props new file mode 100644 index 00000000..ba452462 --- /dev/null +++ b/dtdl-tools/src/dtdl-validator/Directory.Build.props @@ -0,0 +1,7 @@ + + + ../../../target/debug/dtdl-validator/bin + ../../../target/debug/dtdl-validator/obj + ../../../target/debug/dtdl-validator/obj + + diff --git a/dtdl-tools/src/dtdl-validator/DtdlValidator.cs b/dtdl-tools/src/dtdl-validator/DtdlValidator.cs new file mode 100644 index 00000000..8c9ebd52 --- /dev/null +++ b/dtdl-tools/src/dtdl-validator/DtdlValidator.cs @@ -0,0 +1,105 @@ + +using DTDLParser; +using DTDLParser.Models; +using System; +using System.Collections.Generic; +using System.CommandLine; +using System.CommandLine.NamingConventionBinder; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +class Program +{ + // Exit codes. + private const int EXIT_SUCCESS = 0; + private const int EXIT_FAILURE = 1; + + /// + /// This method validates all of the DTDL files with the provided extension that are located + /// under the provided directory. + /// + /// The directory that contains the DTDL files that we wish to validate. + /// The extension used by the DTDL files. + /// + /// EXIT_SUCCESS when all if the DTDL files are valid. + /// EXIT_FAILURE when any of the DTDL files are NOT valid. + /// + static int ValidateDtdl(DirectoryInfo directory, String extension) + { + if (!directory.Exists) + { + Console.WriteLine($"Directory {directory.FullName} does not exist."); + return EXIT_FAILURE; + } + + var files = Directory.GetFiles(directory.FullName, $"*.{extension}", SearchOption.AllDirectories); + + if (!files.Any()) + { + Console.WriteLine($"No files with extension .{extension} found in directory {directory}"); + return EXIT_FAILURE; + } + + var parser = new ModelParser(); + + bool failureOccured = false; + foreach (var file in files) + { + try + { + var dtdl = File.ReadAllText(file); + parser.ParseAsync(dtdl).GetAwaiter().GetResult(); + Console.WriteLine($"{file} - ok"); + } + catch (ParsingException ex) + { + Console.WriteLine($"{file} - failed"); + foreach (var error in ex.Errors) { + Console.WriteLine($" {error}"); + } + failureOccured = true; + } + } + + if (failureOccured) + { + return EXIT_FAILURE; + } + else + { + return EXIT_SUCCESS; + } + } + + static async Task Main(string[] args) + { + var directoryOption = + new Option( + "-d", + getDefaultValue: () => new DirectoryInfo(Directory.GetCurrentDirectory()), + description: "The directory that contains the DTDL files."); + var extensionOption = + new Option( + "-e", + getDefaultValue: () => "json", + description: "The file extension used by the DTDL files."); + + int exitCode = EXIT_SUCCESS; + + var cmd = new RootCommand(); + cmd.AddOption(directoryOption); + cmd.AddOption(extensionOption); + cmd.SetHandler((directory, extension) => + { + exitCode = ValidateDtdl(directory!, extension!); + }, + directoryOption, extensionOption); + + await cmd.InvokeAsync(args); + + return exitCode; + } +} diff --git a/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj b/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj new file mode 100644 index 00000000..240854d5 --- /dev/null +++ b/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj @@ -0,0 +1,14 @@ + + + Exe + net7.0 + + + + + + + + + + diff --git a/dtdl-tools/src/dtdl-validator/licenses.md b/dtdl-tools/src/dtdl-validator/licenses.md new file mode 100644 index 00000000..b69c41a8 --- /dev/null +++ b/dtdl-tools/src/dtdl-validator/licenses.md @@ -0,0 +1,5 @@ + | Reference | Version | License Type | License | + | ----------------------------------------- | ------------------- | ------------ | ------------------------------ | + | DTDLParser | 1.0.52 | MIT | https://licenses.nuget.org/MIT | + | System.CommandLine | 2.0.0-beta4.22272.1 | MIT | https://licenses.nuget.org/MIT | + | System.CommandLine.NamingConventionBinder | 2.0.0-beta4.22272.1 | MIT | https://licenses.nuget.org/MIT | diff --git a/dtdl-tools/src/lib.rs b/dtdl-tools/src/lib.rs new file mode 100644 index 00000000..fbb3db91 --- /dev/null +++ b/dtdl-tools/src/lib.rs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// SPDX-License-Identifier: MIT + +// This lib.rs is for running the .NET unit tests in this digital_twins_connector folder. +// Running 'cargo test' will run all the .NET unit tests and the Rust unit tests. +#[cfg(test)] +mod digital_twins_connector_dotnet_tests { + use std::io::{self, Write}; + use std::path::Path; + use std::process::Command; + + // The manifest directory is the directory that contains the Cargo.toml file for this crate. + const MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR"); + + const DTDL_VALIDATOR_FILENAME: &str = "dtdl-validator"; + const DTDL_VALIDATOR_BIN_DIR: &str = "target/debug/dtdl-validator/bin/Debug/net7.0"; + const DTDL_VALIDATOR_DIR_OPTION: &str = "-d"; + const DTDL_VALIDATOR_EXT_OPTION: &str = "-e"; + + /// Validate DTDL files. + /// + /// # Arguments + /// * `directory` - The directory that contains the DTDL files that you wish to validate. + /// * `extension` - The file extension that the DTDL files use. + fn validate_dtdl_files(directory: &str, extension: &str) -> bool { + + let dtdl_validator_command_path = Path::new(MANIFEST_DIR).join("..").join(DTDL_VALIDATOR_BIN_DIR).join(DTDL_VALIDATOR_FILENAME); + + let dtdl_validator_output = Command::new(dtdl_validator_command_path) + .arg(DTDL_VALIDATOR_DIR_OPTION) + .arg(directory) + .arg(DTDL_VALIDATOR_EXT_OPTION) + .arg(extension) + .output() + .unwrap(); + + if !dtdl_validator_output.status.success() { + io::stdout().write_all(&dtdl_validator_output.stdout).unwrap(); + } + + return dtdl_validator_output.status.success(); + } + + #[test] + fn validate_digital_twin_model_dtdl_files() { + assert!(validate_dtdl_files("../digital-twin-model/dtdl", "json")); + } +} \ No newline at end of file diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 68283abf..7eb23c42 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "nightly-2022-08-11" +channel = "1.72.1" diff --git a/tmp.out b/tmp.out new file mode 100644 index 00000000..fdaac18b --- /dev/null +++ b/tmp.out @@ -0,0 +1,2482 @@ +common v0.1.0 (/home/ashbeitz/repos/ibeji/core/common) +├── bytes feature "default" +│ ├── bytes v1.4.0 +│ └── bytes feature "std" +│ └── bytes v1.4.0 +├── config feature "default" +│ ├── config v0.13.3 +│ │ ├── async-trait feature "default" +│ │ │ └── async-trait v0.1.72 (proc-macro) +│ │ │ ├── proc-macro2 feature "default" +│ │ │ │ ├── proc-macro2 v1.0.66 +│ │ │ │ │ └── unicode-ident feature "default" +│ │ │ │ │ └── unicode-ident v1.0.11 +│ │ │ │ └── proc-macro2 feature "proc-macro" +│ │ │ │ └── proc-macro2 v1.0.66 (*) +│ │ │ ├── quote feature "default" +│ │ │ │ ├── quote v1.0.32 +│ │ │ │ │ └── proc-macro2 v1.0.66 (*) +│ │ │ │ └── quote feature "proc-macro" +│ │ │ │ ├── quote v1.0.32 (*) +│ │ │ │ └── proc-macro2 feature "proc-macro" (*) +│ │ │ ├── syn feature "default" +│ │ │ │ ├── syn v2.0.27 +│ │ │ │ │ ├── proc-macro2 v1.0.66 (*) +│ │ │ │ │ ├── quote v1.0.32 (*) +│ │ │ │ │ └── unicode-ident feature "default" (*) +│ │ │ │ ├── syn feature "clone-impls" +│ │ │ │ │ └── syn v2.0.27 (*) +│ │ │ │ ├── syn feature "derive" +│ │ │ │ │ └── syn v2.0.27 (*) +│ │ │ │ ├── syn feature "parsing" +│ │ │ │ │ └── syn v2.0.27 (*) +│ │ │ │ ├── syn feature "printing" +│ │ │ │ │ ├── syn v2.0.27 (*) +│ │ │ │ │ └── syn feature "quote" +│ │ │ │ │ └── syn v2.0.27 (*) +│ │ │ │ └── syn feature "proc-macro" +│ │ │ │ ├── syn v2.0.27 (*) +│ │ │ │ ├── proc-macro2 feature "proc-macro" (*) +│ │ │ │ ├── quote feature "proc-macro" (*) +│ │ │ │ └── syn feature "quote" (*) +│ │ │ ├── syn feature "full" +│ │ │ │ └── syn v2.0.27 (*) +│ │ │ └── syn feature "visit-mut" +│ │ │ └── syn v2.0.27 (*) +│ │ ├── json5 feature "default" +│ │ │ └── json5 v0.4.1 +│ │ │ ├── pest feature "default" +│ │ │ │ ├── pest v2.7.1 +│ │ │ │ │ ├── ucd-trie v0.1.6 +│ │ │ │ │ └── thiserror feature "default" +│ │ │ │ │ └── thiserror v1.0.44 +│ │ │ │ │ └── thiserror-impl feature "default" +│ │ │ │ │ └── thiserror-impl v1.0.44 (proc-macro) +│ │ │ │ │ ├── proc-macro2 feature "default" (*) +│ │ │ │ │ ├── quote feature "default" (*) +│ │ │ │ │ └── syn feature "default" (*) +│ │ │ │ └── pest feature "std" +│ │ │ │ ├── pest v2.7.1 (*) +│ │ │ │ └── ucd-trie feature "std" +│ │ │ │ └── ucd-trie v0.1.6 +│ │ │ ├── pest_derive feature "default" +│ │ │ │ ├── pest_derive v2.7.1 (proc-macro) +│ │ │ │ │ ├── pest v2.7.1 (*) +│ │ │ │ │ └── pest_generator v2.7.1 +│ │ │ │ │ ├── pest v2.7.1 (*) +│ │ │ │ │ ├── proc-macro2 feature "default" (*) +│ │ │ │ │ ├── quote feature "default" (*) +│ │ │ │ │ ├── syn feature "default" (*) +│ │ │ │ │ └── pest_meta feature "default" +│ │ │ │ │ └── pest_meta v2.7.1 +│ │ │ │ │ ├── pest feature "default" (*) +│ │ │ │ │ └── once_cell feature "default" +│ │ │ │ │ ├── once_cell v1.18.0 +│ │ │ │ │ └── once_cell feature "std" +│ │ │ │ │ ├── once_cell v1.18.0 +│ │ │ │ │ └── once_cell feature "alloc" +│ │ │ │ │ ├── once_cell v1.18.0 +│ │ │ │ │ └── once_cell feature "race" +│ │ │ │ │ └── once_cell v1.18.0 +│ │ │ │ │ [build-dependencies] +│ │ │ │ │ └── sha2 v0.10.7 +│ │ │ │ │ ├── cfg-if feature "default" +│ │ │ │ │ │ └── cfg-if v1.0.0 +│ │ │ │ │ ├── cpufeatures feature "default" +│ │ │ │ │ │ └── cpufeatures v0.2.9 +│ │ │ │ │ └── digest feature "default" +│ │ │ │ │ ├── digest v0.10.7 +│ │ │ │ │ │ ├── block-buffer feature "default" +│ │ │ │ │ │ │ └── block-buffer v0.10.4 +│ │ │ │ │ │ │ └── generic-array feature "default" +│ │ │ │ │ │ │ └── generic-array v0.14.7 +│ │ │ │ │ │ │ └── typenum feature "default" +│ │ │ │ │ │ │ └── typenum v1.16.0 +│ │ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ │ └── version_check feature "default" +│ │ │ │ │ │ │ └── version_check v0.9.4 +│ │ │ │ │ │ └── crypto-common feature "default" +│ │ │ │ │ │ └── crypto-common v0.1.6 +│ │ │ │ │ │ ├── generic-array feature "default" (*) +│ │ │ │ │ │ ├── generic-array feature "more_lengths" +│ │ │ │ │ │ │ └── generic-array v0.14.7 (*) +│ │ │ │ │ │ └── typenum feature "default" (*) +│ │ │ │ │ └── digest feature "core-api" +│ │ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ │ └── digest feature "block-buffer" +│ │ │ │ │ └── digest v0.10.7 (*) +│ │ │ │ └── pest_derive feature "std" +│ │ │ │ ├── pest_derive v2.7.1 (proc-macro) (*) +│ │ │ │ ├── pest feature "std" (*) +│ │ │ │ └── pest_generator feature "std" +│ │ │ │ ├── pest_generator v2.7.1 (*) +│ │ │ │ └── pest feature "std" (*) +│ │ │ └── serde feature "default" +│ │ │ ├── serde v1.0.177 +│ │ │ │ └── serde_derive feature "default" +│ │ │ │ └── serde_derive v1.0.177 (proc-macro) +│ │ │ └── serde feature "std" +│ │ │ └── serde v1.0.177 (*) +│ │ ├── serde feature "default" (*) +│ │ ├── lazy_static feature "default" +│ │ │ └── lazy_static v1.4.0 +│ │ ├── nom feature "default" +│ │ │ ├── nom v7.1.3 +│ │ │ │ ├── memchr v2.5.0 +│ │ │ │ └── minimal-lexical v0.2.1 +│ │ │ └── nom feature "std" +│ │ │ ├── nom v7.1.3 (*) +│ │ │ ├── nom feature "alloc" +│ │ │ │ └── nom v7.1.3 (*) +│ │ │ ├── memchr feature "std" +│ │ │ │ └── memchr v2.5.0 +│ │ │ └── minimal-lexical feature "std" +│ │ │ └── minimal-lexical v0.2.1 +│ │ ├── pathdiff feature "default" +│ │ │ └── pathdiff v0.2.1 +│ │ ├── ron feature "default" +│ │ │ └── ron v0.7.1 +│ │ │ ├── serde feature "default" (*) +│ │ │ ├── serde feature "serde_derive" +│ │ │ │ └── serde v1.0.177 (*) +│ │ │ ├── base64 feature "default" +│ │ │ │ ├── base64 v0.13.1 +│ │ │ │ └── base64 feature "std" +│ │ │ │ └── base64 v0.13.1 +│ │ │ └── bitflags feature "default" +│ │ │ └── bitflags v1.3.2 +│ │ ├── rust-ini feature "default" +│ │ │ └── rust-ini v0.18.0 +│ │ │ ├── cfg-if feature "default" (*) +│ │ │ └── ordered-multimap feature "default" +│ │ │ └── ordered-multimap v0.4.3 +│ │ │ ├── dlv-list feature "default" +│ │ │ │ └── dlv-list v0.3.0 +│ │ │ └── hashbrown feature "default" +│ │ │ ├── hashbrown v0.12.3 +│ │ │ │ └── ahash v0.7.6 +│ │ │ │ ├── once_cell feature "alloc" (*) +│ │ │ │ └── getrandom feature "default" +│ │ │ │ └── getrandom v0.2.10 +│ │ │ │ ├── libc v0.2.147 +│ │ │ │ └── cfg-if feature "default" (*) +│ │ │ │ [build-dependencies] +│ │ │ │ └── version_check feature "default" (*) +│ │ │ ├── hashbrown feature "ahash" +│ │ │ │ └── hashbrown v0.12.3 (*) +│ │ │ └── hashbrown feature "inline-more" +│ │ │ └── hashbrown v0.12.3 (*) +│ │ ├── serde_json feature "default" +│ │ │ ├── serde_json v1.0.104 +│ │ │ │ ├── serde v1.0.177 (*) +│ │ │ │ ├── itoa feature "default" +│ │ │ │ │ └── itoa v1.0.9 +│ │ │ │ └── ryu feature "default" +│ │ │ │ └── ryu v1.0.15 +│ │ │ └── serde_json feature "std" +│ │ │ ├── serde_json v1.0.104 (*) +│ │ │ └── serde feature "std" (*) +│ │ ├── toml feature "default" +│ │ │ └── toml v0.5.11 +│ │ │ └── serde feature "default" (*) +│ │ └── yaml-rust feature "default" +│ │ └── yaml-rust v0.4.5 +│ │ └── linked-hash-map feature "default" +│ │ └── linked-hash-map v0.5.6 +│ ├── config feature "ini" +│ │ ├── config v0.13.3 (*) +│ │ └── config feature "rust-ini" +│ │ └── config v0.13.3 (*) +│ ├── config feature "json" +│ │ ├── config v0.13.3 (*) +│ │ └── config feature "serde_json" +│ │ └── config v0.13.3 (*) +│ ├── config feature "json5" +│ │ ├── config v0.13.3 (*) +│ │ └── config feature "json5_rs" +│ │ └── config v0.13.3 (*) +│ ├── config feature "ron" +│ │ └── config v0.13.3 (*) +│ ├── config feature "toml" +│ │ └── config v0.13.3 (*) +│ └── config feature "yaml" +│ ├── config v0.13.3 (*) +│ └── config feature "yaml-rust" +│ └── config v0.13.3 (*) +├── serde feature "default" (*) +├── serde feature "derive" +│ ├── serde v1.0.177 (*) +│ └── serde feature "serde_derive" (*) +├── serde_derive feature "default" (*) +├── core-protobuf-data-access feature "default" (command-line) +│ └── core-protobuf-data-access v0.1.0 (/home/ashbeitz/repos/ibeji/core/protobuf_data_access) +│ ├── serde feature "default" (*) +│ ├── serde feature "derive" (*) +│ ├── prost feature "default" +│ │ ├── prost v0.12.1 +│ │ │ ├── bytes v1.4.0 +│ │ │ └── prost-derive feature "default" +│ │ │ └── prost-derive v0.12.1 (proc-macro) +│ │ │ ├── proc-macro2 feature "default" (*) +│ │ │ ├── quote feature "default" (*) +│ │ │ ├── syn feature "default" (*) +│ │ │ ├── syn feature "extra-traits" +│ │ │ │ └── syn v2.0.27 (*) +│ │ │ ├── anyhow feature "default" +│ │ │ │ ├── anyhow v1.0.72 +│ │ │ │ └── anyhow feature "std" +│ │ │ │ └── anyhow v1.0.72 +│ │ │ └── itertools feature "use_alloc" +│ │ │ └── itertools v0.10.5 +│ │ │ └── either v1.9.0 +│ │ ├── prost feature "prost-derive" +│ │ │ └── prost v0.12.1 (*) +│ │ └── prost feature "std" +│ │ └── prost v0.12.1 (*) +│ ├── prost-types feature "default" +│ │ ├── prost-types v0.12.1 +│ │ │ └── prost feature "prost-derive" (*) +│ │ └── prost-types feature "std" +│ │ ├── prost-types v0.12.1 (*) +│ │ └── prost feature "std" (*) +│ ├── tokio feature "default" +│ │ └── tokio v1.29.1 +│ │ ├── mio v0.8.8 +│ │ │ ├── libc feature "default" +│ │ │ │ ├── libc v0.2.147 +│ │ │ │ └── libc feature "std" +│ │ │ │ └── libc v0.2.147 +│ │ │ └── log feature "default" +│ │ │ └── log v0.4.19 +│ │ │ └── value-bag v1.4.1 +│ │ ├── bytes feature "default" (*) +│ │ ├── libc feature "default" (*) +│ │ ├── num_cpus feature "default" +│ │ │ └── num_cpus v1.16.0 +│ │ │ └── libc feature "default" (*) +│ │ ├── pin-project-lite feature "default" +│ │ │ └── pin-project-lite v0.2.10 +│ │ ├── signal-hook-registry feature "default" +│ │ │ └── signal-hook-registry v1.4.1 +│ │ │ └── libc feature "default" (*) +│ │ ├── socket2 feature "all" +│ │ │ └── socket2 v0.4.9 +│ │ │ └── libc feature "default" (*) +│ │ ├── socket2 feature "default" +│ │ │ └── socket2 v0.4.9 (*) +│ │ └── tokio-macros feature "default" +│ │ └── tokio-macros v2.1.0 (proc-macro) +│ │ ├── proc-macro2 feature "default" (*) +│ │ ├── quote feature "default" (*) +│ │ ├── syn feature "default" (*) +│ │ └── syn feature "full" (*) +│ │ [build-dependencies] +│ │ └── autocfg feature "default" +│ │ └── autocfg v1.1.0 +│ ├── tokio feature "macros" +│ │ ├── tokio v1.29.1 (*) +│ │ └── tokio feature "tokio-macros" +│ │ └── tokio v1.29.1 (*) +│ ├── tokio feature "rt-multi-thread" +│ │ ├── tokio v1.29.1 (*) +│ │ ├── tokio feature "num_cpus" +│ │ │ └── tokio v1.29.1 (*) +│ │ └── tokio feature "rt" +│ │ └── tokio v1.29.1 (*) +│ └── tonic feature "default" +│ ├── tonic v0.10.0 +│ │ ├── axum v0.6.19 +│ │ │ ├── bytes feature "default" (*) +│ │ │ ├── async-trait feature "default" (*) +│ │ │ ├── serde feature "default" (*) +│ │ │ ├── memchr feature "default" +│ │ │ │ ├── memchr v2.5.0 +│ │ │ │ └── memchr feature "std" (*) +│ │ │ ├── bitflags feature "default" (*) +│ │ │ ├── itoa feature "default" (*) +│ │ │ ├── pin-project-lite feature "default" (*) +│ │ │ ├── axum-core feature "default" +│ │ │ │ └── axum-core v0.3.4 +│ │ │ │ ├── bytes feature "default" (*) +│ │ │ │ ├── async-trait feature "default" (*) +│ │ │ │ ├── futures-util feature "alloc" +│ │ │ │ │ ├── futures-util v0.3.28 +│ │ │ │ │ │ ├── futures-core v0.3.28 +│ │ │ │ │ │ ├── futures-macro v0.3.28 (proc-macro) +│ │ │ │ │ │ │ ├── proc-macro2 feature "default" (*) +│ │ │ │ │ │ │ ├── quote feature "default" (*) +│ │ │ │ │ │ │ ├── syn feature "default" (*) +│ │ │ │ │ │ │ └── syn feature "full" (*) +│ │ │ │ │ │ ├── futures-sink v0.3.28 +│ │ │ │ │ │ ├── futures-task v0.3.28 +│ │ │ │ │ │ ├── memchr feature "default" (*) +│ │ │ │ │ │ ├── pin-project-lite feature "default" (*) +│ │ │ │ │ │ ├── futures-channel feature "std" +│ │ │ │ │ │ │ ├── futures-channel v0.3.28 +│ │ │ │ │ │ │ │ ├── futures-core v0.3.28 +│ │ │ │ │ │ │ │ └── futures-sink v0.3.28 +│ │ │ │ │ │ │ ├── futures-core feature "std" +│ │ │ │ │ │ │ │ ├── futures-core v0.3.28 +│ │ │ │ │ │ │ │ └── futures-core feature "alloc" +│ │ │ │ │ │ │ │ └── futures-core v0.3.28 +│ │ │ │ │ │ │ └── futures-channel feature "alloc" +│ │ │ │ │ │ │ ├── futures-channel v0.3.28 (*) +│ │ │ │ │ │ │ └── futures-core feature "alloc" (*) +│ │ │ │ │ │ ├── futures-io feature "std" +│ │ │ │ │ │ │ └── futures-io v0.3.28 +│ │ │ │ │ │ ├── pin-utils feature "default" +│ │ │ │ │ │ │ └── pin-utils v0.1.0 +│ │ │ │ │ │ └── slab feature "default" +│ │ │ │ │ │ ├── slab v0.4.8 +│ │ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ │ └── autocfg feature "default" (*) +│ │ │ │ │ │ └── slab feature "std" +│ │ │ │ │ │ └── slab v0.4.8 (*) +│ │ │ │ │ ├── futures-core feature "alloc" (*) +│ │ │ │ │ └── futures-task feature "alloc" +│ │ │ │ │ └── futures-task v0.3.28 +│ │ │ │ ├── http feature "default" +│ │ │ │ │ └── http v0.2.9 +│ │ │ │ │ ├── bytes feature "default" (*) +│ │ │ │ │ ├── itoa feature "default" (*) +│ │ │ │ │ └── fnv feature "default" +│ │ │ │ │ ├── fnv v1.0.7 +│ │ │ │ │ └── fnv feature "std" +│ │ │ │ │ └── fnv v1.0.7 +│ │ │ │ ├── http-body feature "default" +│ │ │ │ │ └── http-body v0.4.5 +│ │ │ │ │ ├── bytes feature "default" (*) +│ │ │ │ │ ├── pin-project-lite feature "default" (*) +│ │ │ │ │ └── http feature "default" (*) +│ │ │ │ ├── mime feature "default" +│ │ │ │ │ └── mime v0.3.17 +│ │ │ │ ├── tower-layer feature "default" +│ │ │ │ │ └── tower-layer v0.3.2 +│ │ │ │ └── tower-service feature "default" +│ │ │ │ └── tower-service v0.3.2 +│ │ │ │ [build-dependencies] +│ │ │ │ └── rustversion feature "default" +│ │ │ │ └── rustversion v1.0.14 (proc-macro) +│ │ │ ├── futures-util feature "alloc" (*) +│ │ │ ├── http feature "default" (*) +│ │ │ ├── http-body feature "default" (*) +│ │ │ ├── mime feature "default" (*) +│ │ │ ├── tower-layer feature "default" (*) +│ │ │ ├── tower-service feature "default" (*) +│ │ │ ├── hyper feature "default" +│ │ │ │ └── hyper v0.14.27 +│ │ │ │ ├── futures-core v0.3.28 +│ │ │ │ ├── futures-util v0.3.28 (*) +│ │ │ │ ├── bytes feature "default" (*) +│ │ │ │ ├── itoa feature "default" (*) +│ │ │ │ ├── tokio feature "default" (*) +│ │ │ │ ├── tokio feature "sync" +│ │ │ │ │ └── tokio v1.29.1 (*) +│ │ │ │ ├── pin-project-lite feature "default" (*) +│ │ │ │ ├── socket2 feature "all" (*) +│ │ │ │ ├── socket2 feature "default" (*) +│ │ │ │ ├── futures-channel feature "default" +│ │ │ │ │ ├── futures-channel v0.3.28 (*) +│ │ │ │ │ └── futures-channel feature "std" (*) +│ │ │ │ ├── http feature "default" (*) +│ │ │ │ ├── http-body feature "default" (*) +│ │ │ │ ├── tower-service feature "default" (*) +│ │ │ │ ├── h2 feature "default" +│ │ │ │ │ └── h2 v0.3.20 +│ │ │ │ │ ├── futures-core v0.3.28 +│ │ │ │ │ ├── futures-sink v0.3.28 +│ │ │ │ │ ├── futures-util v0.3.28 (*) +│ │ │ │ │ ├── bytes feature "default" (*) +│ │ │ │ │ ├── tokio feature "default" (*) +│ │ │ │ │ ├── tokio feature "io-util" +│ │ │ │ │ │ ├── tokio v1.29.1 (*) +│ │ │ │ │ │ └── tokio feature "bytes" +│ │ │ │ │ │ └── tokio v1.29.1 (*) +│ │ │ │ │ ├── slab feature "default" (*) +│ │ │ │ │ ├── http feature "default" (*) +│ │ │ │ │ ├── fnv feature "default" (*) +│ │ │ │ │ ├── indexmap feature "default" +│ │ │ │ │ │ └── indexmap v1.9.3 +│ │ │ │ │ │ └── hashbrown feature "raw" +│ │ │ │ │ │ └── hashbrown v0.12.3 (*) +│ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ └── autocfg feature "default" (*) +│ │ │ │ │ ├── indexmap feature "std" +│ │ │ │ │ │ └── indexmap v1.9.3 (*) +│ │ │ │ │ ├── tokio-util feature "codec" +│ │ │ │ │ │ ├── tokio-util v0.7.8 +│ │ │ │ │ │ │ ├── bytes feature "default" (*) +│ │ │ │ │ │ │ ├── tokio feature "default" (*) +│ │ │ │ │ │ │ ├── tokio feature "sync" (*) +│ │ │ │ │ │ │ ├── pin-project-lite feature "default" (*) +│ │ │ │ │ │ │ ├── futures-core feature "default" +│ │ │ │ │ │ │ │ ├── futures-core v0.3.28 +│ │ │ │ │ │ │ │ └── futures-core feature "std" (*) +│ │ │ │ │ │ │ ├── futures-sink feature "default" +│ │ │ │ │ │ │ │ ├── futures-sink v0.3.28 +│ │ │ │ │ │ │ │ └── futures-sink feature "std" +│ │ │ │ │ │ │ │ ├── futures-sink v0.3.28 +│ │ │ │ │ │ │ │ └── futures-sink feature "alloc" +│ │ │ │ │ │ │ │ └── futures-sink v0.3.28 +│ │ │ │ │ │ │ └── tracing feature "std" +│ │ │ │ │ │ │ ├── tracing v0.1.37 +│ │ │ │ │ │ │ │ ├── tracing-core v0.1.31 +│ │ │ │ │ │ │ │ │ └── once_cell feature "default" (*) +│ │ │ │ │ │ │ │ ├── cfg-if feature "default" (*) +│ │ │ │ │ │ │ │ ├── log feature "default" (*) +│ │ │ │ │ │ │ │ ├── pin-project-lite feature "default" (*) +│ │ │ │ │ │ │ │ └── tracing-attributes feature "default" +│ │ │ │ │ │ │ │ └── tracing-attributes v0.1.26 (proc-macro) +│ │ │ │ │ │ │ │ ├── proc-macro2 feature "default" (*) +│ │ │ │ │ │ │ │ ├── quote feature "default" (*) +│ │ │ │ │ │ │ │ ├── syn feature "clone-impls" (*) +│ │ │ │ │ │ │ │ ├── syn feature "extra-traits" (*) +│ │ │ │ │ │ │ │ ├── syn feature "full" (*) +│ │ │ │ │ │ │ │ ├── syn feature "parsing" (*) +│ │ │ │ │ │ │ │ ├── syn feature "printing" (*) +│ │ │ │ │ │ │ │ ├── syn feature "proc-macro" (*) +│ │ │ │ │ │ │ │ └── syn feature "visit-mut" (*) +│ │ │ │ │ │ │ └── tracing-core feature "std" +│ │ │ │ │ │ │ ├── tracing-core v0.1.31 (*) +│ │ │ │ │ │ │ └── tracing-core feature "once_cell" +│ │ │ │ │ │ │ └── tracing-core v0.1.31 (*) +│ │ │ │ │ │ └── tokio-util feature "tracing" +│ │ │ │ │ │ └── tokio-util v0.7.8 (*) +│ │ │ │ │ ├── tokio-util feature "default" +│ │ │ │ │ │ └── tokio-util v0.7.8 (*) +│ │ │ │ │ └── tracing feature "std" (*) +│ │ │ │ ├── tracing feature "std" (*) +│ │ │ │ ├── httparse feature "default" +│ │ │ │ │ ├── httparse v1.8.0 +│ │ │ │ │ └── httparse feature "std" +│ │ │ │ │ └── httparse v1.8.0 +│ │ │ │ ├── httpdate feature "default" +│ │ │ │ │ └── httpdate v1.0.2 +│ │ │ │ └── want feature "default" +│ │ │ │ └── want v0.3.1 +│ │ │ │ └── try-lock feature "default" +│ │ │ │ └── try-lock v0.2.4 +│ │ │ ├── hyper feature "stream" +│ │ │ │ └── hyper v0.14.27 (*) +│ │ │ ├── matchit feature "default" +│ │ │ │ └── matchit v0.7.0 +│ │ │ ├── percent-encoding feature "default" +│ │ │ │ ├── percent-encoding v2.3.0 +│ │ │ │ └── percent-encoding feature "std" +│ │ │ │ ├── percent-encoding v2.3.0 +│ │ │ │ └── percent-encoding feature "alloc" +│ │ │ │ └── percent-encoding v2.3.0 +│ │ │ ├── sync_wrapper feature "default" +│ │ │ │ └── sync_wrapper v0.1.2 +│ │ │ └── tower feature "util" +│ │ │ ├── tower v0.4.13 +│ │ │ │ ├── tokio-util v0.7.8 (*) +│ │ │ │ ├── tokio feature "default" (*) +│ │ │ │ ├── tokio feature "sync" (*) +│ │ │ │ ├── pin-project-lite feature "default" (*) +│ │ │ │ ├── futures-core feature "default" (*) +│ │ │ │ ├── futures-util feature "alloc" (*) +│ │ │ │ ├── slab feature "default" (*) +│ │ │ │ ├── tower-layer feature "default" (*) +│ │ │ │ ├── tower-service feature "default" (*) +│ │ │ │ ├── indexmap feature "default" (*) +│ │ │ │ ├── tracing feature "std" (*) +│ │ │ │ ├── pin-project feature "default" +│ │ │ │ │ └── pin-project v1.1.2 +│ │ │ │ │ └── pin-project-internal feature "default" +│ │ │ │ │ └── pin-project-internal v1.1.2 (proc-macro) +│ │ │ │ │ ├── proc-macro2 feature "default" (*) +│ │ │ │ │ ├── quote feature "default" (*) +│ │ │ │ │ ├── syn feature "default" (*) +│ │ │ │ │ ├── syn feature "full" (*) +│ │ │ │ │ └── syn feature "visit-mut" (*) +│ │ │ │ ├── rand feature "default" +│ │ │ │ │ ├── rand v0.8.5 +│ │ │ │ │ │ ├── libc v0.2.147 +│ │ │ │ │ │ ├── rand_chacha v0.3.1 +│ │ │ │ │ │ │ ├── ppv-lite86 feature "simd" +│ │ │ │ │ │ │ │ └── ppv-lite86 v0.2.17 +│ │ │ │ │ │ │ └── rand_core feature "default" +│ │ │ │ │ │ │ └── rand_core v0.6.4 +│ │ │ │ │ │ │ └── getrandom feature "default" (*) +│ │ │ │ │ │ └── rand_core feature "default" (*) +│ │ │ │ │ ├── rand feature "std" +│ │ │ │ │ │ ├── rand v0.8.5 (*) +│ │ │ │ │ │ ├── rand feature "alloc" +│ │ │ │ │ │ │ ├── rand v0.8.5 (*) +│ │ │ │ │ │ │ └── rand_core feature "alloc" +│ │ │ │ │ │ │ └── rand_core v0.6.4 (*) +│ │ │ │ │ │ ├── rand feature "getrandom" +│ │ │ │ │ │ │ ├── rand v0.8.5 (*) +│ │ │ │ │ │ │ └── rand_core feature "getrandom" +│ │ │ │ │ │ │ └── rand_core v0.6.4 (*) +│ │ │ │ │ │ ├── rand feature "libc" +│ │ │ │ │ │ │ └── rand v0.8.5 (*) +│ │ │ │ │ │ ├── rand feature "rand_chacha" +│ │ │ │ │ │ │ └── rand v0.8.5 (*) +│ │ │ │ │ │ ├── rand_chacha feature "std" +│ │ │ │ │ │ │ ├── rand_chacha v0.3.1 (*) +│ │ │ │ │ │ │ └── ppv-lite86 feature "std" +│ │ │ │ │ │ │ └── ppv-lite86 v0.2.17 +│ │ │ │ │ │ └── rand_core feature "std" +│ │ │ │ │ │ ├── rand_core v0.6.4 (*) +│ │ │ │ │ │ ├── getrandom feature "std" +│ │ │ │ │ │ │ └── getrandom v0.2.10 (*) +│ │ │ │ │ │ ├── rand_core feature "alloc" (*) +│ │ │ │ │ │ └── rand_core feature "getrandom" (*) +│ │ │ │ │ └── rand feature "std_rng" +│ │ │ │ │ ├── rand v0.8.5 (*) +│ │ │ │ │ └── rand feature "rand_chacha" (*) +│ │ │ │ └── rand feature "small_rng" +│ │ │ │ └── rand v0.8.5 (*) +│ │ │ ├── tower feature "__common" +│ │ │ │ ├── tower v0.4.13 (*) +│ │ │ │ ├── tower feature "futures-core" +│ │ │ │ │ └── tower v0.4.13 (*) +│ │ │ │ └── tower feature "pin-project-lite" +│ │ │ │ └── tower v0.4.13 (*) +│ │ │ ├── tower feature "futures-util" +│ │ │ │ └── tower v0.4.13 (*) +│ │ │ └── tower feature "pin-project" +│ │ │ └── tower v0.4.13 (*) +│ │ │ [build-dependencies] +│ │ │ └── rustversion feature "default" (*) +│ │ ├── bytes feature "default" (*) +│ │ ├── async-trait feature "default" (*) +│ │ ├── prost feature "std" (*) +│ │ ├── tokio feature "default" (*) +│ │ ├── async-stream feature "default" +│ │ │ └── async-stream v0.3.5 +│ │ │ ├── pin-project-lite feature "default" (*) +│ │ │ ├── async-stream-impl feature "default" +│ │ │ │ └── async-stream-impl v0.3.5 (proc-macro) +│ │ │ │ ├── proc-macro2 feature "default" (*) +│ │ │ │ ├── quote feature "default" (*) +│ │ │ │ ├── syn feature "default" (*) +│ │ │ │ ├── syn feature "full" (*) +│ │ │ │ └── syn feature "visit-mut" (*) +│ │ │ └── futures-core feature "default" (*) +│ │ ├── http feature "default" (*) +│ │ ├── http-body feature "default" (*) +│ │ ├── tower-layer feature "default" (*) +│ │ ├── tower-service feature "default" (*) +│ │ ├── hyper feature "default" (*) +│ │ ├── hyper feature "full" +│ │ │ ├── hyper v0.14.27 (*) +│ │ │ ├── hyper feature "client" +│ │ │ │ └── hyper v0.14.27 (*) +│ │ │ ├── hyper feature "http1" +│ │ │ │ └── hyper v0.14.27 (*) +│ │ │ ├── hyper feature "http2" +│ │ │ │ ├── hyper v0.14.27 (*) +│ │ │ │ └── hyper feature "h2" +│ │ │ │ └── hyper v0.14.27 (*) +│ │ │ ├── hyper feature "runtime" +│ │ │ │ ├── hyper v0.14.27 (*) +│ │ │ │ ├── tokio feature "rt" (*) +│ │ │ │ ├── tokio feature "time" +│ │ │ │ │ └── tokio v1.29.1 (*) +│ │ │ │ └── hyper feature "tcp" +│ │ │ │ ├── hyper v0.14.27 (*) +│ │ │ │ ├── tokio feature "net" +│ │ │ │ │ ├── tokio v1.29.1 (*) +│ │ │ │ │ ├── tokio feature "libc" +│ │ │ │ │ │ └── tokio v1.29.1 (*) +│ │ │ │ │ ├── tokio feature "mio" +│ │ │ │ │ │ └── tokio v1.29.1 (*) +│ │ │ │ │ ├── tokio feature "socket2" +│ │ │ │ │ │ └── tokio v1.29.1 (*) +│ │ │ │ │ ├── mio feature "net" +│ │ │ │ │ │ └── mio v0.8.8 (*) +│ │ │ │ │ ├── mio feature "os-ext" +│ │ │ │ │ │ ├── mio v0.8.8 (*) +│ │ │ │ │ │ └── mio feature "os-poll" +│ │ │ │ │ │ └── mio v0.8.8 (*) +│ │ │ │ │ └── mio feature "os-poll" (*) +│ │ │ │ ├── tokio feature "rt" (*) +│ │ │ │ ├── tokio feature "time" (*) +│ │ │ │ └── hyper feature "socket2" +│ │ │ │ └── hyper v0.14.27 (*) +│ │ │ ├── hyper feature "server" +│ │ │ │ └── hyper v0.14.27 (*) +│ │ │ └── hyper feature "stream" (*) +│ │ ├── h2 feature "default" (*) +│ │ ├── tracing feature "default" +│ │ │ ├── tracing v0.1.37 (*) +│ │ │ ├── tracing feature "attributes" +│ │ │ │ ├── tracing v0.1.37 (*) +│ │ │ │ └── tracing feature "tracing-attributes" +│ │ │ │ └── tracing v0.1.37 (*) +│ │ │ └── tracing feature "std" (*) +│ │ ├── percent-encoding feature "default" (*) +│ │ ├── tower feature "balance" +│ │ │ ├── tower v0.4.13 (*) +│ │ │ ├── tower feature "discover" +│ │ │ │ ├── tower v0.4.13 (*) +│ │ │ │ └── tower feature "__common" (*) +│ │ │ ├── tower feature "load" +│ │ │ │ ├── tower v0.4.13 (*) +│ │ │ │ ├── tokio feature "time" (*) +│ │ │ │ ├── tower feature "__common" (*) +│ │ │ │ ├── tower feature "tokio" +│ │ │ │ │ └── tower v0.4.13 (*) +│ │ │ │ └── tower feature "tracing" +│ │ │ │ └── tower v0.4.13 (*) +│ │ │ ├── tower feature "make" +│ │ │ │ ├── tower v0.4.13 (*) +│ │ │ │ ├── tokio feature "io-std" +│ │ │ │ │ └── tokio v1.29.1 (*) +│ │ │ │ ├── tower feature "futures-util" (*) +│ │ │ │ ├── tower feature "pin-project-lite" (*) +│ │ │ │ └── tower feature "tokio" (*) +│ │ │ ├── tower feature "rand" +│ │ │ │ └── tower v0.4.13 (*) +│ │ │ ├── tower feature "ready-cache" +│ │ │ │ ├── tower v0.4.13 (*) +│ │ │ │ ├── tokio feature "sync" (*) +│ │ │ │ ├── tower feature "futures-core" (*) +│ │ │ │ ├── tower feature "futures-util" (*) +│ │ │ │ ├── tower feature "indexmap" +│ │ │ │ │ └── tower v0.4.13 (*) +│ │ │ │ ├── tower feature "pin-project-lite" (*) +│ │ │ │ ├── tower feature "tokio" (*) +│ │ │ │ └── tower feature "tracing" (*) +│ │ │ └── tower feature "slab" +│ │ │ └── tower v0.4.13 (*) +│ │ ├── tower feature "buffer" +│ │ │ ├── tower v0.4.13 (*) +│ │ │ ├── tokio feature "rt" (*) +│ │ │ ├── tokio feature "sync" (*) +│ │ │ ├── tower feature "__common" (*) +│ │ │ ├── tower feature "tokio" (*) +│ │ │ ├── tower feature "tokio-util" +│ │ │ │ └── tower v0.4.13 (*) +│ │ │ └── tower feature "tracing" (*) +│ │ ├── tower feature "discover" (*) +│ │ ├── tower feature "limit" +│ │ │ ├── tower v0.4.13 (*) +│ │ │ ├── tokio feature "sync" (*) +│ │ │ ├── tokio feature "time" (*) +│ │ │ ├── tower feature "__common" (*) +│ │ │ ├── tower feature "tokio" (*) +│ │ │ ├── tower feature "tokio-util" (*) +│ │ │ └── tower feature "tracing" (*) +│ │ ├── tower feature "load" (*) +│ │ ├── tower feature "make" (*) +│ │ ├── tower feature "timeout" +│ │ │ ├── tower v0.4.13 (*) +│ │ │ ├── tokio feature "time" (*) +│ │ │ ├── tower feature "pin-project-lite" (*) +│ │ │ └── tower feature "tokio" (*) +│ │ ├── tower feature "util" (*) +│ │ ├── pin-project feature "default" (*) +│ │ ├── base64 feature "default" +│ │ │ ├── base64 v0.21.2 +│ │ │ └── base64 feature "std" +│ │ │ └── base64 v0.21.2 +│ │ ├── hyper-timeout feature "default" +│ │ │ └── hyper-timeout v0.4.1 +│ │ │ ├── tokio feature "default" (*) +│ │ │ ├── pin-project-lite feature "default" (*) +│ │ │ ├── hyper feature "client" (*) +│ │ │ ├── hyper feature "default" (*) +│ │ │ └── tokio-io-timeout feature "default" +│ │ │ └── tokio-io-timeout v1.2.0 +│ │ │ ├── tokio feature "default" (*) +│ │ │ ├── tokio feature "time" (*) +│ │ │ └── pin-project-lite feature "default" (*) +│ │ └── tokio-stream feature "default" +│ │ ├── tokio-stream v0.1.14 +│ │ │ ├── tokio feature "default" (*) +│ │ │ ├── tokio feature "sync" (*) +│ │ │ ├── pin-project-lite feature "default" (*) +│ │ │ └── futures-core feature "default" (*) +│ │ └── tokio-stream feature "time" +│ │ ├── tokio-stream v0.1.14 (*) +│ │ └── tokio feature "time" (*) +│ ├── tonic feature "codegen" +│ │ └── tonic v0.10.0 (*) +│ ├── tonic feature "prost" +│ │ └── tonic v0.10.0 (*) +│ └── tonic feature "transport" +│ ├── tonic v0.10.0 (*) +│ ├── tokio feature "net" (*) +│ ├── tokio feature "time" (*) +│ └── tonic feature "channel" +│ └── tonic v0.10.0 (*) +│ [build-dependencies] +│ └── tonic-build feature "default" +│ ├── tonic-build v0.10.0 +│ │ ├── proc-macro2 feature "default" (*) +│ │ ├── quote feature "default" (*) +│ │ ├── syn feature "default" (*) +│ │ ├── prettyplease feature "default" +│ │ │ └── prettyplease v0.2.12 +│ │ │ ├── proc-macro2 v1.0.66 (*) +│ │ │ └── syn feature "full" (*) +│ │ └── prost-build feature "default" +│ │ ├── prost-build v0.12.1 +│ │ │ ├── bytes v1.4.0 +│ │ │ ├── multimap v0.8.3 +│ │ │ ├── petgraph v0.6.3 +│ │ │ │ ├── fixedbitset v0.4.2 +│ │ │ │ ├── indexmap feature "default" (*) +│ │ │ │ └── indexmap feature "std" (*) +│ │ │ ├── prost v0.12.1 +│ │ │ │ ├── bytes v1.4.0 +│ │ │ │ └── prost-derive feature "default" (*) +│ │ │ ├── prost-types v0.12.1 +│ │ │ │ └── prost feature "prost-derive" +│ │ │ │ └── prost v0.12.1 (*) +│ │ │ ├── syn feature "default" (*) +│ │ │ ├── syn feature "full" (*) +│ │ │ ├── once_cell feature "default" (*) +│ │ │ ├── itertools feature "use_alloc" (*) +│ │ │ ├── prettyplease feature "default" (*) +│ │ │ ├── heck feature "default" +│ │ │ │ └── heck v0.4.1 +│ │ │ ├── log feature "default" +│ │ │ │ └── log v0.4.19 +│ │ │ ├── regex feature "std" +│ │ │ │ ├── regex v1.9.3 +│ │ │ │ │ ├── regex-syntax v0.7.4 +│ │ │ │ │ ├── regex-automata feature "alloc" +│ │ │ │ │ │ └── regex-automata v0.3.6 +│ │ │ │ │ │ └── regex-syntax v0.7.4 +│ │ │ │ │ ├── regex-automata feature "meta" +│ │ │ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ │ │ ├── regex-automata feature "nfa-pikevm" +│ │ │ │ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ │ │ │ └── regex-automata feature "nfa-thompson" +│ │ │ │ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ │ │ │ └── regex-automata feature "alloc" (*) +│ │ │ │ │ │ └── regex-automata feature "syntax" +│ │ │ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ │ │ └── regex-automata feature "alloc" (*) +│ │ │ │ │ ├── regex-automata feature "nfa-pikevm" (*) +│ │ │ │ │ └── regex-automata feature "syntax" (*) +│ │ │ │ ├── regex-automata feature "std" +│ │ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ │ ├── regex-automata feature "alloc" (*) +│ │ │ │ │ └── regex-syntax feature "std" +│ │ │ │ │ └── regex-syntax v0.7.4 +│ │ │ │ └── regex-syntax feature "std" (*) +│ │ │ ├── regex feature "unicode-bool" +│ │ │ │ ├── regex v1.9.3 (*) +│ │ │ │ ├── regex-automata feature "unicode-bool" +│ │ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ │ └── regex-syntax feature "unicode-bool" +│ │ │ │ │ └── regex-syntax v0.7.4 +│ │ │ │ └── regex-syntax feature "unicode-bool" (*) +│ │ │ ├── tempfile feature "default" +│ │ │ │ └── tempfile v3.7.0 +│ │ │ │ ├── cfg-if feature "default" (*) +│ │ │ │ ├── fastrand feature "default" +│ │ │ │ │ ├── fastrand v2.0.0 +│ │ │ │ │ └── fastrand feature "std" +│ │ │ │ │ ├── fastrand v2.0.0 +│ │ │ │ │ └── fastrand feature "alloc" +│ │ │ │ │ └── fastrand v2.0.0 +│ │ │ │ ├── rustix feature "default" +│ │ │ │ │ ├── rustix v0.38.4 +│ │ │ │ │ │ ├── bitflags v2.3.3 +│ │ │ │ │ │ ├── linux-raw-sys feature "errno" +│ │ │ │ │ │ │ └── linux-raw-sys v0.4.3 +│ │ │ │ │ │ ├── linux-raw-sys feature "general" +│ │ │ │ │ │ │ └── linux-raw-sys v0.4.3 +│ │ │ │ │ │ ├── linux-raw-sys feature "ioctl" +│ │ │ │ │ │ │ └── linux-raw-sys v0.4.3 +│ │ │ │ │ │ └── linux-raw-sys feature "no_std" +│ │ │ │ │ │ └── linux-raw-sys v0.4.3 +│ │ │ │ │ ├── rustix feature "std" +│ │ │ │ │ │ ├── rustix v0.38.4 (*) +│ │ │ │ │ │ └── bitflags feature "std" +│ │ │ │ │ │ └── bitflags v2.3.3 +│ │ │ │ │ └── rustix feature "use-libc-auxv" +│ │ │ │ │ └── rustix v0.38.4 (*) +│ │ │ │ └── rustix feature "fs" +│ │ │ │ └── rustix v0.38.4 (*) +│ │ │ └── which feature "default" +│ │ │ └── which v4.4.0 +│ │ │ ├── either feature "default" +│ │ │ │ ├── either v1.9.0 +│ │ │ │ └── either feature "use_std" +│ │ │ │ └── either v1.9.0 +│ │ │ └── libc feature "default" +│ │ │ ├── libc v0.2.147 +│ │ │ └── libc feature "std" +│ │ │ └── libc v0.2.147 +│ │ └── prost-build feature "format" +│ │ ├── prost-build v0.12.1 (*) +│ │ ├── prost-build feature "prettyplease" +│ │ │ └── prost-build v0.12.1 (*) +│ │ └── prost-build feature "syn" +│ │ └── prost-build v0.12.1 (*) +│ ├── tonic-build feature "prost" +│ │ ├── tonic-build v0.10.0 (*) +│ │ └── tonic-build feature "prost-build" +│ │ └── tonic-build v0.10.0 (*) +│ └── tonic-build feature "transport" +│ └── tonic-build v0.10.0 (*) +├── prost feature "default" (*) +├── tokio feature "default" (*) +├── log feature "default" (*) +├── tonic feature "default" (*) +├── futures-core feature "default" (*) +├── futures-util feature "default" +│ ├── futures-util v0.3.28 (*) +│ ├── futures-util feature "async-await" +│ │ └── futures-util v0.3.28 (*) +│ ├── futures-util feature "async-await-macro" +│ │ ├── futures-util v0.3.28 (*) +│ │ ├── futures-util feature "async-await" (*) +│ │ └── futures-util feature "futures-macro" +│ │ └── futures-util v0.3.28 (*) +│ └── futures-util feature "std" +│ ├── futures-util v0.3.28 (*) +│ ├── futures-core feature "std" (*) +│ ├── futures-util feature "alloc" (*) +│ ├── futures-util feature "slab" +│ │ └── futures-util v0.3.28 (*) +│ └── futures-task feature "std" +│ ├── futures-task v0.3.28 +│ └── futures-task feature "alloc" (*) +├── http feature "default" (*) +├── http-body feature "default" (*) +├── hyper feature "default" (*) +├── tower feature "default" +│ ├── tower v0.4.13 (*) +│ └── tower feature "log" +│ ├── tower v0.4.13 (*) +│ ├── tracing feature "log" +│ │ └── tracing v0.1.37 (*) +│ └── tower feature "tracing" (*) +├── dyn-clone feature "default" +│ └── dyn-clone v1.0.14 +├── futures feature "default" +│ ├── futures v0.3.28 +│ │ ├── futures-core v0.3.28 +│ │ ├── futures-executor v0.3.28 +│ │ │ ├── futures-core v0.3.28 +│ │ │ ├── futures-task v0.3.28 +│ │ │ └── futures-util v0.3.28 (*) +│ │ ├── futures-io v0.3.28 +│ │ ├── futures-sink v0.3.28 +│ │ ├── futures-task v0.3.28 +│ │ ├── futures-util feature "sink" +│ │ │ ├── futures-util v0.3.28 (*) +│ │ │ └── futures-util feature "futures-sink" +│ │ │ └── futures-util v0.3.28 (*) +│ │ └── futures-channel feature "sink" +│ │ ├── futures-channel v0.3.28 (*) +│ │ └── futures-channel feature "futures-sink" +│ │ └── futures-channel v0.3.28 (*) +│ ├── futures feature "async-await" +│ │ ├── futures v0.3.28 (*) +│ │ ├── futures-util feature "async-await" (*) +│ │ └── futures-util feature "async-await-macro" (*) +│ ├── futures feature "executor" +│ │ ├── futures v0.3.28 (*) +│ │ ├── futures feature "futures-executor" +│ │ │ └── futures v0.3.28 (*) +│ │ ├── futures feature "std" +│ │ │ ├── futures v0.3.28 (*) +│ │ │ ├── futures-core feature "std" (*) +│ │ │ ├── futures-util feature "channel" +│ │ │ │ ├── futures-util v0.3.28 (*) +│ │ │ │ ├── futures-util feature "futures-channel" +│ │ │ │ │ └── futures-util v0.3.28 (*) +│ │ │ │ └── futures-util feature "std" (*) +│ │ │ ├── futures-util feature "io" +│ │ │ │ ├── futures-util v0.3.28 (*) +│ │ │ │ ├── futures-util feature "futures-io" +│ │ │ │ │ └── futures-util v0.3.28 (*) +│ │ │ │ ├── futures-util feature "memchr" +│ │ │ │ │ └── futures-util v0.3.28 (*) +│ │ │ │ └── futures-util feature "std" (*) +│ │ │ ├── futures-util feature "std" (*) +│ │ │ ├── futures-sink feature "std" (*) +│ │ │ ├── futures-io feature "std" (*) +│ │ │ ├── futures-task feature "std" (*) +│ │ │ └── futures feature "alloc" +│ │ │ ├── futures v0.3.28 (*) +│ │ │ ├── futures-core feature "alloc" (*) +│ │ │ ├── futures-util feature "alloc" (*) +│ │ │ ├── futures-channel feature "alloc" (*) +│ │ │ ├── futures-sink feature "alloc" (*) +│ │ │ └── futures-task feature "alloc" (*) +│ │ └── futures-executor feature "std" +│ │ ├── futures-executor v0.3.28 (*) +│ │ ├── futures-core feature "std" (*) +│ │ ├── futures-util feature "std" (*) +│ │ └── futures-task feature "std" (*) +│ └── futures feature "std" (*) +├── parking_lot feature "default" +│ └── parking_lot v0.12.1 +│ ├── lock_api feature "default" +│ │ ├── lock_api v0.4.10 +│ │ │ └── scopeguard v1.2.0 +│ │ │ [build-dependencies] +│ │ │ └── autocfg feature "default" (*) +│ │ └── lock_api feature "atomic_usize" +│ │ └── lock_api v0.4.10 (*) +│ └── parking_lot_core feature "default" +│ └── parking_lot_core v0.9.8 +│ ├── cfg-if feature "default" (*) +│ ├── libc feature "default" (*) +│ └── smallvec feature "default" +│ └── smallvec v1.11.0 +├── regex feature "default" +│ ├── regex v1.9.3 +│ │ ├── regex-syntax v0.7.4 +│ │ ├── memchr feature "default" (*) +│ │ ├── aho-corasick feature "default" +│ │ │ ├── aho-corasick v1.0.2 +│ │ │ │ └── memchr v2.5.0 +│ │ │ ├── aho-corasick feature "perf-literal" +│ │ │ │ └── aho-corasick v1.0.2 (*) +│ │ │ └── aho-corasick feature "std" +│ │ │ ├── aho-corasick v1.0.2 (*) +│ │ │ └── memchr feature "std" (*) +│ │ ├── regex-automata feature "alloc" +│ │ │ └── regex-automata v0.3.6 +│ │ │ ├── aho-corasick v1.0.2 (*) +│ │ │ ├── memchr v2.5.0 +│ │ │ └── regex-syntax v0.7.4 +│ │ ├── regex-automata feature "meta" +│ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ ├── regex-automata feature "nfa-pikevm" +│ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ └── regex-automata feature "nfa-thompson" +│ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ └── regex-automata feature "alloc" (*) +│ │ │ └── regex-automata feature "syntax" +│ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ └── regex-automata feature "alloc" (*) +│ │ ├── regex-automata feature "nfa-pikevm" (*) +│ │ └── regex-automata feature "syntax" (*) +│ ├── regex feature "perf" +│ │ ├── regex v1.9.3 (*) +│ │ ├── regex feature "perf-backtrack" +│ │ │ ├── regex v1.9.3 (*) +│ │ │ └── regex-automata feature "nfa-backtrack" +│ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ └── regex-automata feature "nfa-thompson" (*) +│ │ ├── regex feature "perf-cache" +│ │ │ └── regex v1.9.3 (*) +│ │ ├── regex feature "perf-dfa" +│ │ │ ├── regex v1.9.3 (*) +│ │ │ └── regex-automata feature "hybrid" +│ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ ├── regex-automata feature "alloc" (*) +│ │ │ └── regex-automata feature "nfa-thompson" (*) +│ │ ├── regex feature "perf-inline" +│ │ │ ├── regex v1.9.3 (*) +│ │ │ └── regex-automata feature "perf-inline" +│ │ │ └── regex-automata v0.3.6 (*) +│ │ ├── regex feature "perf-literal" +│ │ │ ├── regex v1.9.3 (*) +│ │ │ └── regex-automata feature "perf-literal" +│ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ ├── regex-automata feature "perf-literal-multisubstring" +│ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ └── regex-automata feature "std" +│ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ ├── memchr feature "std" (*) +│ │ │ │ ├── aho-corasick feature "std" (*) +│ │ │ │ ├── regex-automata feature "alloc" (*) +│ │ │ │ └── regex-syntax feature "std" +│ │ │ │ └── regex-syntax v0.7.4 +│ │ │ └── regex-automata feature "perf-literal-substring" +│ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ └── aho-corasick feature "perf-literal" (*) +│ │ └── regex feature "perf-onepass" +│ │ ├── regex v1.9.3 (*) +│ │ └── regex-automata feature "dfa-onepass" +│ │ ├── regex-automata v0.3.6 (*) +│ │ └── regex-automata feature "nfa-thompson" (*) +│ ├── regex feature "std" +│ │ ├── regex v1.9.3 (*) +│ │ ├── memchr feature "std" (*) +│ │ ├── aho-corasick feature "std" (*) +│ │ ├── regex-automata feature "std" (*) +│ │ └── regex-syntax feature "std" (*) +│ ├── regex feature "unicode" +│ │ ├── regex v1.9.3 (*) +│ │ ├── regex feature "unicode-age" +│ │ │ ├── regex v1.9.3 (*) +│ │ │ ├── regex-automata feature "unicode-age" +│ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ └── regex-syntax feature "unicode-age" +│ │ │ │ └── regex-syntax v0.7.4 +│ │ │ └── regex-syntax feature "unicode-age" (*) +│ │ ├── regex feature "unicode-bool" +│ │ │ ├── regex v1.9.3 (*) +│ │ │ ├── regex-automata feature "unicode-bool" +│ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ └── regex-syntax feature "unicode-bool" +│ │ │ │ └── regex-syntax v0.7.4 +│ │ │ └── regex-syntax feature "unicode-bool" (*) +│ │ ├── regex feature "unicode-case" +│ │ │ ├── regex v1.9.3 (*) +│ │ │ ├── regex-automata feature "unicode-case" +│ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ └── regex-syntax feature "unicode-case" +│ │ │ │ └── regex-syntax v0.7.4 +│ │ │ └── regex-syntax feature "unicode-case" (*) +│ │ ├── regex feature "unicode-gencat" +│ │ │ ├── regex v1.9.3 (*) +│ │ │ ├── regex-automata feature "unicode-gencat" +│ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ └── regex-syntax feature "unicode-gencat" +│ │ │ │ └── regex-syntax v0.7.4 +│ │ │ └── regex-syntax feature "unicode-gencat" (*) +│ │ ├── regex feature "unicode-perl" +│ │ │ ├── regex v1.9.3 (*) +│ │ │ ├── regex-automata feature "unicode-perl" +│ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ └── regex-syntax feature "unicode-perl" +│ │ │ │ └── regex-syntax v0.7.4 +│ │ │ ├── regex-automata feature "unicode-word-boundary" +│ │ │ │ └── regex-automata v0.3.6 (*) +│ │ │ └── regex-syntax feature "unicode-perl" (*) +│ │ ├── regex feature "unicode-script" +│ │ │ ├── regex v1.9.3 (*) +│ │ │ ├── regex-automata feature "unicode-script" +│ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ └── regex-syntax feature "unicode-script" +│ │ │ │ └── regex-syntax v0.7.4 +│ │ │ └── regex-syntax feature "unicode-script" (*) +│ │ ├── regex feature "unicode-segment" +│ │ │ ├── regex v1.9.3 (*) +│ │ │ ├── regex-automata feature "unicode-segment" +│ │ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ │ └── regex-syntax feature "unicode-segment" +│ │ │ │ └── regex-syntax v0.7.4 +│ │ │ └── regex-syntax feature "unicode-segment" (*) +│ │ ├── regex-automata feature "unicode" +│ │ │ ├── regex-automata v0.3.6 (*) +│ │ │ ├── regex-automata feature "unicode-age" (*) +│ │ │ ├── regex-automata feature "unicode-bool" (*) +│ │ │ ├── regex-automata feature "unicode-case" (*) +│ │ │ ├── regex-automata feature "unicode-gencat" (*) +│ │ │ ├── regex-automata feature "unicode-perl" (*) +│ │ │ ├── regex-automata feature "unicode-script" (*) +│ │ │ ├── regex-automata feature "unicode-segment" (*) +│ │ │ ├── regex-automata feature "unicode-word-boundary" (*) +│ │ │ └── regex-syntax feature "unicode" +│ │ │ ├── regex-syntax v0.7.4 +│ │ │ ├── regex-syntax feature "unicode-age" (*) +│ │ │ ├── regex-syntax feature "unicode-bool" (*) +│ │ │ ├── regex-syntax feature "unicode-case" (*) +│ │ │ ├── regex-syntax feature "unicode-gencat" (*) +│ │ │ ├── regex-syntax feature "unicode-perl" (*) +│ │ │ ├── regex-syntax feature "unicode-script" (*) +│ │ │ └── regex-syntax feature "unicode-segment" (*) +│ │ └── regex-syntax feature "unicode" (*) +│ └── regex-syntax feature "default" +│ ├── regex-syntax v0.7.4 +│ ├── regex-syntax feature "std" (*) +│ └── regex-syntax feature "unicode" (*) +└── url feature "default" + └── url v2.4.0 + ├── percent-encoding feature "default" (*) + ├── form_urlencoded feature "default" + │ ├── form_urlencoded v1.2.0 + │ │ └── percent-encoding v2.3.0 + │ └── form_urlencoded feature "std" + │ ├── form_urlencoded v1.2.0 (*) + │ ├── percent-encoding feature "std" (*) + │ └── form_urlencoded feature "alloc" + │ ├── form_urlencoded v1.2.0 (*) + │ └── percent-encoding feature "alloc" (*) + └── idna feature "default" + ├── idna v0.4.0 + │ ├── unicode-normalization v0.1.22 + │ │ ├── tinyvec feature "alloc" + │ │ │ ├── tinyvec v1.6.0 + │ │ │ │ └── tinyvec_macros feature "default" + │ │ │ │ └── tinyvec_macros v0.1.1 + │ │ │ └── tinyvec feature "tinyvec_macros" + │ │ │ └── tinyvec v1.6.0 (*) + │ │ └── tinyvec feature "default" + │ │ └── tinyvec v1.6.0 (*) + │ └── unicode-bidi feature "hardcoded-data" + │ └── unicode-bidi v0.3.13 + └── idna feature "std" + ├── idna v0.4.0 (*) + ├── idna feature "alloc" + │ └── idna v0.4.0 (*) + ├── unicode-bidi feature "std" + │ └── unicode-bidi v0.3.13 + └── unicode-normalization feature "std" + └── unicode-normalization v0.1.22 (*) +[build-dependencies] +└── tonic-build feature "default" (*) + +core-protobuf-data-access v0.1.0 (/home/ashbeitz/repos/ibeji/core/protobuf_data_access) (*) + +digital-twin-model v0.1.0 (/home/ashbeitz/repos/ibeji/digital-twin-model) +├── serde feature "default" (*) +└── serde_derive feature "default" (*) + +dtdl-tools v0.1.0 (/home/ashbeitz/repos/ibeji/dtdl-tools) + +invehicle-digital-twin v0.1.0 (/home/ashbeitz/repos/ibeji/core/invehicle-digital-twin) +├── common feature "default" (command-line) +│ └── common v0.1.0 (/home/ashbeitz/repos/ibeji/core/common) (*) +├── bytes feature "default" (*) +├── config feature "default" (*) +├── serde feature "default" (*) +├── serde feature "derive" (*) +├── serde_derive feature "default" (*) +├── serde_json feature "default" (*) +├── yaml-rust feature "default" (*) +├── core-protobuf-data-access feature "default" (command-line) (*) +├── prost feature "default" (*) +├── tokio feature "default" (*) +├── tokio feature "macros" (*) +├── tokio feature "rt-multi-thread" (*) +├── log feature "default" (*) +├── tonic feature "default" (*) +├── http feature "default" (*) +├── tower feature "default" (*) +├── futures feature "default" (*) +├── parking_lot feature "default" (*) +├── url feature "default" (*) +├── async-std feature "attributes" +│ ├── async-std v1.12.0 +│ │ ├── futures-core v0.3.28 +│ │ ├── once_cell feature "default" (*) +│ │ ├── memchr feature "default" (*) +│ │ ├── log feature "default" (*) +│ │ ├── log feature "kv_unstable" +│ │ │ ├── log v0.4.19 (*) +│ │ │ └── log feature "value-bag" +│ │ │ └── log v0.4.19 (*) +│ │ ├── pin-project-lite feature "default" (*) +│ │ ├── futures-io feature "default" +│ │ │ ├── futures-io v0.3.28 +│ │ │ └── futures-io feature "std" (*) +│ │ ├── pin-utils feature "default" (*) +│ │ ├── slab feature "default" (*) +│ │ ├── async-attributes feature "default" +│ │ │ └── async-attributes v1.1.2 (proc-macro) +│ │ │ ├── quote feature "default" (*) +│ │ │ ├── syn feature "default" +│ │ │ │ ├── syn v1.0.109 +│ │ │ │ │ ├── proc-macro2 v1.0.66 (*) +│ │ │ │ │ ├── quote v1.0.32 (*) +│ │ │ │ │ └── unicode-ident feature "default" (*) +│ │ │ │ ├── syn feature "clone-impls" +│ │ │ │ │ └── syn v1.0.109 (*) +│ │ │ │ ├── syn feature "derive" +│ │ │ │ │ └── syn v1.0.109 (*) +│ │ │ │ ├── syn feature "parsing" +│ │ │ │ │ └── syn v1.0.109 (*) +│ │ │ │ ├── syn feature "printing" +│ │ │ │ │ ├── syn v1.0.109 (*) +│ │ │ │ │ └── syn feature "quote" +│ │ │ │ │ └── syn v1.0.109 (*) +│ │ │ │ └── syn feature "proc-macro" +│ │ │ │ ├── syn v1.0.109 (*) +│ │ │ │ ├── proc-macro2 feature "proc-macro" (*) +│ │ │ │ ├── quote feature "proc-macro" (*) +│ │ │ │ └── syn feature "quote" (*) +│ │ │ └── syn feature "full" +│ │ │ └── syn v1.0.109 (*) +│ │ ├── async-channel feature "default" +│ │ │ └── async-channel v1.9.0 +│ │ │ ├── futures-core feature "default" (*) +│ │ │ ├── concurrent-queue feature "default" +│ │ │ │ ├── concurrent-queue v2.2.0 +│ │ │ │ │ └── crossbeam-utils v0.8.16 +│ │ │ │ │ └── cfg-if feature "default" (*) +│ │ │ │ └── concurrent-queue feature "std" +│ │ │ │ └── concurrent-queue v2.2.0 (*) +│ │ │ └── event-listener feature "default" +│ │ │ └── event-listener v2.5.3 +│ │ ├── crossbeam-utils feature "default" +│ │ │ ├── crossbeam-utils v0.8.16 (*) +│ │ │ └── crossbeam-utils feature "std" +│ │ │ └── crossbeam-utils v0.8.16 (*) +│ │ ├── async-global-executor feature "async-io" +│ │ │ └── async-global-executor v2.3.1 +│ │ │ ├── once_cell feature "default" (*) +│ │ │ ├── async-channel feature "default" (*) +│ │ │ ├── async-executor feature "default" +│ │ │ │ └── async-executor v1.5.1 +│ │ │ │ ├── slab feature "default" (*) +│ │ │ │ ├── concurrent-queue feature "default" (*) +│ │ │ │ ├── async-lock feature "default" +│ │ │ │ │ └── async-lock v2.7.0 +│ │ │ │ │ └── event-listener feature "default" (*) +│ │ │ │ ├── async-task feature "default" +│ │ │ │ │ ├── async-task v4.4.0 +│ │ │ │ │ └── async-task feature "std" +│ │ │ │ │ └── async-task v4.4.0 +│ │ │ │ ├── fastrand feature "default" +│ │ │ │ │ └── fastrand v1.9.0 +│ │ │ │ └── futures-lite feature "default" +│ │ │ │ ├── futures-lite v1.13.0 +│ │ │ │ │ ├── futures-core v0.3.28 +│ │ │ │ │ ├── memchr feature "default" (*) +│ │ │ │ │ ├── pin-project-lite feature "default" (*) +│ │ │ │ │ ├── futures-io feature "default" (*) +│ │ │ │ │ ├── fastrand feature "default" (*) +│ │ │ │ │ ├── parking feature "default" +│ │ │ │ │ │ └── parking v2.1.0 +│ │ │ │ │ └── waker-fn feature "default" +│ │ │ │ │ └── waker-fn v1.1.0 +│ │ │ │ └── futures-lite feature "std" +│ │ │ │ ├── futures-lite v1.13.0 (*) +│ │ │ │ ├── futures-lite feature "alloc" +│ │ │ │ │ └── futures-lite v1.13.0 (*) +│ │ │ │ ├── futures-lite feature "fastrand" +│ │ │ │ │ └── futures-lite v1.13.0 (*) +│ │ │ │ ├── futures-lite feature "futures-io" +│ │ │ │ │ └── futures-lite v1.13.0 (*) +│ │ │ │ ├── futures-lite feature "memchr" +│ │ │ │ │ └── futures-lite v1.13.0 (*) +│ │ │ │ ├── futures-lite feature "parking" +│ │ │ │ │ └── futures-lite v1.13.0 (*) +│ │ │ │ └── futures-lite feature "waker-fn" +│ │ │ │ └── futures-lite v1.13.0 (*) +│ │ │ ├── async-lock feature "default" (*) +│ │ │ ├── futures-lite feature "default" (*) +│ │ │ ├── async-io feature "default" +│ │ │ │ └── async-io v1.13.0 +│ │ │ │ ├── cfg-if feature "default" (*) +│ │ │ │ ├── log feature "default" (*) +│ │ │ │ ├── socket2 feature "all" (*) +│ │ │ │ ├── socket2 feature "default" (*) +│ │ │ │ ├── slab feature "default" (*) +│ │ │ │ ├── concurrent-queue feature "default" (*) +│ │ │ │ ├── async-lock feature "default" (*) +│ │ │ │ ├── futures-lite feature "default" (*) +│ │ │ │ ├── parking feature "default" (*) +│ │ │ │ ├── waker-fn feature "default" (*) +│ │ │ │ ├── polling feature "default" +│ │ │ │ │ ├── polling v2.8.0 +│ │ │ │ │ │ ├── cfg-if feature "default" (*) +│ │ │ │ │ │ ├── libc feature "default" (*) +│ │ │ │ │ │ └── log feature "default" (*) +│ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ └── autocfg feature "default" (*) +│ │ │ │ │ └── polling feature "std" +│ │ │ │ │ └── polling v2.8.0 (*) +│ │ │ │ ├── rustix feature "fs" +│ │ │ │ │ └── rustix v0.37.23 +│ │ │ │ │ ├── bitflags feature "default" (*) +│ │ │ │ │ ├── io-lifetimes feature "close" +│ │ │ │ │ │ ├── io-lifetimes v1.0.11 +│ │ │ │ │ │ │ └── libc feature "default" (*) +│ │ │ │ │ │ ├── io-lifetimes feature "hermit-abi" +│ │ │ │ │ │ │ └── io-lifetimes v1.0.11 (*) +│ │ │ │ │ │ ├── io-lifetimes feature "libc" +│ │ │ │ │ │ │ └── io-lifetimes v1.0.11 (*) +│ │ │ │ │ │ └── io-lifetimes feature "windows-sys" +│ │ │ │ │ │ └── io-lifetimes v1.0.11 (*) +│ │ │ │ │ ├── linux-raw-sys feature "errno" +│ │ │ │ │ │ └── linux-raw-sys v0.3.8 +│ │ │ │ │ ├── linux-raw-sys feature "general" +│ │ │ │ │ │ └── linux-raw-sys v0.3.8 +│ │ │ │ │ ├── linux-raw-sys feature "ioctl" +│ │ │ │ │ │ └── linux-raw-sys v0.3.8 +│ │ │ │ │ └── linux-raw-sys feature "no_std" +│ │ │ │ │ └── linux-raw-sys v0.3.8 +│ │ │ │ └── rustix feature "std" +│ │ │ │ ├── rustix v0.37.23 (*) +│ │ │ │ └── rustix feature "io-lifetimes" +│ │ │ │ └── rustix v0.37.23 (*) +│ │ │ │ [build-dependencies] +│ │ │ │ └── autocfg feature "default" (*) +│ │ │ └── blocking feature "default" +│ │ │ └── blocking v1.3.1 +│ │ │ ├── log feature "default" (*) +│ │ │ ├── async-channel feature "default" (*) +│ │ │ ├── async-lock feature "default" (*) +│ │ │ ├── async-task feature "default" (*) +│ │ │ ├── fastrand feature "default" (*) +│ │ │ ├── futures-lite feature "default" (*) +│ │ │ └── atomic-waker feature "default" +│ │ │ └── atomic-waker v1.1.1 +│ │ ├── async-global-executor feature "default" +│ │ │ ├── async-global-executor v2.3.1 (*) +│ │ │ └── async-global-executor feature "async-io" (*) +│ │ ├── async-lock feature "default" (*) +│ │ ├── futures-lite feature "default" (*) +│ │ ├── async-io feature "default" (*) +│ │ └── kv-log-macro feature "default" +│ │ └── kv-log-macro v1.0.7 +│ │ ├── log feature "default" (*) +│ │ └── log feature "kv_unstable" (*) +│ └── async-std feature "async-attributes" +│ └── async-std v1.12.0 (*) +├── async-std feature "default" +│ ├── async-std v1.12.0 (*) +│ ├── async-std feature "async-global-executor" +│ │ └── async-std v1.12.0 (*) +│ ├── async-std feature "async-io" +│ │ └── async-std v1.12.0 (*) +│ ├── async-std feature "futures-lite" +│ │ └── async-std v1.12.0 (*) +│ ├── async-std feature "gloo-timers" +│ │ └── async-std v1.12.0 (*) +│ ├── async-std feature "kv-log-macro" +│ │ └── async-std v1.12.0 (*) +│ ├── async-std feature "log" +│ │ └── async-std v1.12.0 (*) +│ ├── async-std feature "pin-project-lite" +│ │ └── async-std v1.12.0 (*) +│ └── async-std feature "std" +│ ├── async-std v1.12.0 (*) +│ ├── futures-core feature "std" (*) +│ ├── async-std feature "alloc" +│ │ ├── async-std v1.12.0 (*) +│ │ ├── futures-core feature "alloc" (*) +│ │ ├── async-std feature "futures-core" +│ │ │ └── async-std v1.12.0 (*) +│ │ └── async-std feature "pin-project-lite" (*) +│ ├── async-std feature "async-channel" +│ │ └── async-std v1.12.0 (*) +│ ├── async-std feature "async-lock" +│ │ └── async-std v1.12.0 (*) +│ ├── async-std feature "crossbeam-utils" +│ │ └── async-std v1.12.0 (*) +│ ├── async-std feature "futures-channel" +│ │ └── async-std v1.12.0 (*) +│ ├── async-std feature "futures-core" (*) +│ ├── async-std feature "futures-io" +│ │ └── async-std v1.12.0 (*) +│ ├── async-std feature "memchr" +│ │ └── async-std v1.12.0 (*) +│ ├── async-std feature "once_cell" +│ │ └── async-std v1.12.0 (*) +│ ├── async-std feature "pin-utils" +│ │ └── async-std v1.12.0 (*) +│ ├── async-std feature "slab" +│ │ └── async-std v1.12.0 (*) +│ └── async-std feature "wasm-bindgen-futures" +│ └── async-std v1.12.0 (*) +├── env_logger feature "default" +│ ├── env_logger v0.10.0 +│ │ ├── log feature "default" (*) +│ │ ├── log feature "std" +│ │ │ └── log v0.4.19 (*) +│ │ ├── regex feature "perf" (*) +│ │ ├── regex feature "std" (*) +│ │ ├── humantime feature "default" +│ │ │ └── humantime v2.1.0 +│ │ ├── is-terminal feature "default" +│ │ │ └── is-terminal v0.4.9 +│ │ │ ├── rustix feature "default" +│ │ │ │ ├── rustix v0.38.4 +│ │ │ │ │ ├── bitflags v2.3.3 +│ │ │ │ │ ├── linux-raw-sys feature "errno" (*) +│ │ │ │ │ ├── linux-raw-sys feature "general" (*) +│ │ │ │ │ ├── linux-raw-sys feature "ioctl" (*) +│ │ │ │ │ └── linux-raw-sys feature "no_std" (*) +│ │ │ │ ├── rustix feature "std" +│ │ │ │ │ ├── rustix v0.38.4 (*) +│ │ │ │ │ └── bitflags feature "std" (*) +│ │ │ │ └── rustix feature "use-libc-auxv" +│ │ │ │ └── rustix v0.38.4 (*) +│ │ │ └── rustix feature "termios" +│ │ │ └── rustix v0.38.4 (*) +│ │ └── termcolor feature "default" +│ │ └── termcolor v1.2.0 +│ ├── env_logger feature "auto-color" +│ │ ├── env_logger v0.10.0 (*) +│ │ └── env_logger feature "color" +│ │ └── env_logger v0.10.0 (*) +│ ├── env_logger feature "humantime" +│ │ └── env_logger v0.10.0 (*) +│ └── env_logger feature "regex" +│ └── env_logger v0.10.0 (*) +├── iref feature "default" +│ └── iref v2.2.3 +│ ├── smallvec feature "default" (*) +│ └── pct-str feature "default" +│ └── pct-str v1.2.0 +│ └── utf8-decode feature "default" +│ └── utf8-decode v1.0.1 +├── managed_subscribe feature "default" (command-line) +│ └── managed_subscribe v0.1.0 (/home/ashbeitz/repos/ibeji/core/module/managed_subscribe) +│ ├── common feature "default" (command-line) (*) +│ ├── bytes feature "default" (*) +│ ├── serde feature "default" (*) +│ ├── serde feature "derive" (*) +│ ├── serde_derive feature "default" (*) +│ ├── yaml-rust feature "default" (*) +│ ├── core-protobuf-data-access feature "default" (command-line) (*) +│ ├── prost feature "default" (*) +│ ├── tokio feature "default" (*) +│ ├── tokio feature "macros" (*) +│ ├── tokio feature "rt-multi-thread" (*) +│ ├── log feature "default" (*) +│ ├── tonic feature "default" (*) +│ ├── tower feature "default" (*) +│ ├── dyn-clone feature "default" (*) +│ ├── parking_lot feature "default" (*) +│ ├── strum feature "default" +│ │ ├── strum v0.25.0 +│ │ └── strum feature "std" +│ │ └── strum v0.25.0 +│ └── strum_macros feature "default" +│ └── strum_macros v0.25.1 (proc-macro) +│ ├── proc-macro2 feature "default" (*) +│ ├── quote feature "default" (*) +│ ├── syn feature "default" (*) +│ ├── syn feature "extra-traits" (*) +│ ├── syn feature "parsing" (*) +│ ├── rustversion feature "default" (*) +│ └── heck feature "default" (*) +│ [build-dependencies] +│ └── tonic-build feature "default" (*) +├── strum feature "default" (*) +└── strum_macros feature "default" (*) +[build-dependencies] +└── tonic-build feature "default" (*) + +managed_subscribe v0.1.0 (/home/ashbeitz/repos/ibeji/core/module/managed_subscribe) (*) + +samples-command v0.1.0 (/home/ashbeitz/repos/ibeji/samples/command) +├── serde feature "default" (*) +├── serde_derive feature "default" (*) +├── serde_json feature "default" (*) +├── prost feature "default" (*) +├── tokio feature "default" (*) +├── tokio feature "macros" (*) +├── tokio feature "rt-multi-thread" (*) +├── log feature "default" (*) +├── tonic feature "default" (*) +├── tokio-stream feature "default" (*) +├── parking_lot feature "default" (*) +├── digital-twin-model feature "default" (command-line) +│ └── digital-twin-model v0.1.0 (/home/ashbeitz/repos/ibeji/digital-twin-model) (*) +├── async-std feature "attributes" (*) +├── async-std feature "default" (*) +├── env_logger feature "default" (*) +├── samples-common feature "default" (command-line) +│ ├── samples-common v0.1.0 (/home/ashbeitz/repos/ibeji/samples/common) +│ │ ├── config feature "default" (*) +│ │ ├── serde feature "default" (*) +│ │ ├── serde feature "derive" (*) +│ │ ├── serde_derive feature "default" (*) +│ │ ├── yaml-rust feature "default" (*) +│ │ ├── tokio feature "default" (*) +│ │ ├── log feature "default" (*) +│ │ ├── tonic feature "default" (*) +│ │ └── samples-protobuf-data-access feature "default" (command-line) +│ │ └── samples-protobuf-data-access v1.0.0 (/home/ashbeitz/repos/ibeji/samples/protobuf_data_access) +│ │ ├── serde feature "default" (*) +│ │ ├── serde feature "derive" (*) +│ │ ├── prost feature "default" (*) +│ │ ├── prost-types feature "default" (*) +│ │ ├── tokio feature "default" (*) +│ │ ├── tokio feature "macros" (*) +│ │ ├── tokio feature "rt-multi-thread" (*) +│ │ └── tonic feature "default" (*) +│ │ [build-dependencies] +│ │ └── tonic-build feature "default" (*) +│ └── samples-common feature "yaml" +│ ├── samples-common v0.1.0 (/home/ashbeitz/repos/ibeji/samples/common) (*) +│ └── samples-common feature "yaml-rust" +│ └── samples-common v0.1.0 (/home/ashbeitz/repos/ibeji/samples/common) (*) +├── samples-protobuf-data-access feature "default" (command-line) (*) +├── uuid feature "default" +│ ├── uuid v1.4.1 +│ │ ├── getrandom feature "default" (*) +│ │ ├── rand feature "default" (*) +│ │ └── uuid-macro-internal feature "default" +│ │ └── uuid-macro-internal v1.4.1 (proc-macro) +│ │ ├── proc-macro2 feature "default" (*) +│ │ ├── proc-macro2 feature "span-locations" +│ │ │ └── proc-macro2 v1.0.66 (*) +│ │ ├── quote feature "default" (*) +│ │ └── syn feature "default" (*) +│ └── uuid feature "std" +│ └── uuid v1.4.1 (*) +├── uuid feature "fast-rng" +│ ├── uuid v1.4.1 (*) +│ ├── uuid feature "rand" +│ │ └── uuid v1.4.1 (*) +│ └── uuid feature "rng" +│ ├── uuid v1.4.1 (*) +│ └── uuid feature "getrandom" +│ └── uuid v1.4.1 (*) +├── uuid feature "macro-diagnostics" +│ ├── uuid v1.4.1 (*) +│ └── uuid feature "uuid-macro-internal" +│ └── uuid v1.4.1 (*) +└── uuid feature "v4" + ├── uuid v1.4.1 (*) + └── uuid feature "rng" (*) +[build-dependencies] +└── tonic-build feature "default" (*) + +samples-common v0.1.0 (/home/ashbeitz/repos/ibeji/samples/common) (*) + +samples-managed-subscribe v0.1.0 (/home/ashbeitz/repos/ibeji/samples/managed_subscribe) +├── serde feature "default" (*) +├── serde_derive feature "default" (*) +├── serde_json feature "default" (*) +├── prost feature "default" (*) +├── tokio feature "default" (*) +├── tokio feature "macros" (*) +├── tokio feature "rt-multi-thread" (*) +├── tokio feature "signal" +│ ├── tokio v1.29.1 (*) +│ ├── tokio feature "libc" (*) +│ ├── tokio feature "mio" (*) +│ ├── tokio feature "signal-hook-registry" +│ │ └── tokio v1.29.1 (*) +│ ├── mio feature "net" (*) +│ ├── mio feature "os-ext" (*) +│ └── mio feature "os-poll" (*) +├── log feature "default" (*) +├── tonic feature "default" (*) +├── parking_lot feature "default" (*) +├── url feature "default" (*) +├── digital-twin-model feature "default" (command-line) (*) +├── async-std feature "attributes" (*) +├── async-std feature "default" (*) +├── env_logger feature "default" (*) +├── strum feature "default" (*) +├── strum_macros feature "default" (*) +├── samples-common feature "default" (command-line) (*) +├── samples-protobuf-data-access feature "default" (command-line) (*) +├── uuid feature "default" (*) +├── uuid feature "fast-rng" (*) +├── uuid feature "macro-diagnostics" (*) +├── uuid feature "v4" (*) +└── paho-mqtt feature "default" + ├── paho-mqtt v0.12.1 + │ ├── paho-mqtt-sys v0.8.1 + │ │ └── openssl-sys feature "default" + │ │ └── openssl-sys v0.9.90 + │ │ └── libc feature "default" (*) + │ │ [build-dependencies] + │ │ ├── cc feature "default" + │ │ │ └── cc v1.0.79 + │ │ └── pkg-config feature "default" + │ │ └── pkg-config v0.3.27 + │ │ [build-dependencies] + │ │ └── cmake feature "default" + │ │ └── cmake v0.1.50 + │ │ └── cc feature "default" (*) + │ ├── thiserror feature "default" (*) + │ ├── libc feature "default" (*) + │ ├── log feature "default" (*) + │ ├── futures feature "default" (*) + │ ├── async-channel feature "default" (*) + │ ├── crossbeam-channel feature "default" + │ │ ├── crossbeam-channel v0.5.8 + │ │ │ ├── crossbeam-utils v0.8.16 (*) + │ │ │ └── cfg-if feature "default" (*) + │ │ └── crossbeam-channel feature "std" + │ │ ├── crossbeam-channel v0.5.8 (*) + │ │ ├── crossbeam-utils feature "std" (*) + │ │ └── crossbeam-channel feature "crossbeam-utils" + │ │ └── crossbeam-channel v0.5.8 (*) + │ └── futures-timer feature "default" + │ └── futures-timer v3.0.2 + ├── paho-mqtt feature "bundled" + │ ├── paho-mqtt v0.12.1 (*) + │ └── paho-mqtt-sys feature "bundled" + │ ├── paho-mqtt-sys v0.8.1 (*) + │ └── paho-mqtt-sys feature "cmake" + │ └── paho-mqtt-sys v0.8.1 (*) + └── paho-mqtt feature "ssl" + ├── paho-mqtt v0.12.1 (*) + └── paho-mqtt-sys feature "ssl" + ├── paho-mqtt-sys v0.8.1 (*) + └── paho-mqtt-sys feature "openssl-sys" + └── paho-mqtt-sys v0.8.1 (*) +[build-dependencies] +└── tonic-build feature "default" (*) + +samples-mixed v0.1.0 (/home/ashbeitz/repos/ibeji/samples/mixed) +├── serde feature "default" (*) +├── serde_derive feature "default" (*) +├── serde_json feature "default" (*) +├── prost feature "default" (*) +├── tokio feature "default" (*) +├── tokio feature "macros" (*) +├── tokio feature "rt-multi-thread" (*) +├── log feature "default" (*) +├── tonic feature "default" (*) +├── tokio-stream feature "default" (*) +├── parking_lot feature "default" (*) +├── digital-twin-model feature "default" (command-line) (*) +├── async-std feature "attributes" (*) +├── async-std feature "default" (*) +├── env_logger feature "default" (*) +├── samples-common feature "default" (command-line) (*) +├── samples-protobuf-data-access feature "default" (command-line) (*) +├── uuid feature "default" (*) +├── uuid feature "fast-rng" (*) +├── uuid feature "macro-diagnostics" (*) +└── uuid feature "v4" (*) +[build-dependencies] +└── tonic-build feature "default" (*) + +samples-property v0.1.0 (/home/ashbeitz/repos/ibeji/samples/property) +├── serde feature "default" (*) +├── serde_derive feature "default" (*) +├── serde_json feature "default" (*) +├── prost feature "default" (*) +├── tokio feature "default" (*) +├── tokio feature "macros" (*) +├── tokio feature "rt-multi-thread" (*) +├── tokio feature "signal" (*) +├── log feature "default" (*) +├── tonic feature "default" (*) +├── parking_lot feature "default" (*) +├── url feature "default" (*) +├── digital-twin-model feature "default" (command-line) (*) +├── async-std feature "attributes" (*) +├── async-std feature "default" (*) +├── env_logger feature "default" (*) +├── samples-common feature "default" (command-line) (*) +├── samples-protobuf-data-access feature "default" (command-line) (*) +├── uuid feature "default" (*) +├── uuid feature "fast-rng" (*) +├── uuid feature "macro-diagnostics" (*) +├── uuid feature "v4" (*) +└── paho-mqtt feature "default" (*) +[build-dependencies] +└── tonic-build feature "default" (*) + +samples-protobuf-data-access v1.0.0 (/home/ashbeitz/repos/ibeji/samples/protobuf_data_access) (*) + +samples-seat-massager v0.1.0 (/home/ashbeitz/repos/ibeji/samples/seat_massager) +├── serde feature "default" (*) +├── serde_derive feature "default" (*) +├── serde_json feature "default" (*) +├── tokio feature "default" (*) +├── tokio feature "macros" (*) +├── tokio feature "rt-multi-thread" (*) +├── log feature "default" (*) +├── tonic feature "default" (*) +├── tokio-stream feature "default" (*) +├── parking_lot feature "default" (*) +├── digital-twin-model feature "default" (command-line) (*) +├── async-std feature "attributes" (*) +├── async-std feature "default" (*) +├── env_logger feature "default" (*) +├── samples-common feature "default" (command-line) (*) +└── samples-protobuf-data-access feature "default" (command-line) (*) +[build-dependencies] +└── tonic-build feature "default" (*) + +samples-streaming v0.1.0 (/home/ashbeitz/repos/ibeji/samples/streaming) +├── config feature "default" (*) +├── serde feature "default" (*) +├── serde feature "derive" (*) +├── serde_derive feature "default" (*) +├── serde_json feature "default" (*) +├── yaml-rust feature "default" (*) +├── prost feature "default" (*) +├── tokio feature "default" (*) +├── tokio feature "macros" (*) +├── tokio feature "rt-multi-thread" (*) +├── tokio feature "signal" (*) +├── tokio feature "sync" (*) +├── log feature "default" (*) +├── tonic feature "default" (*) +├── tokio-stream feature "default" (*) +├── parking_lot feature "default" (*) +├── url feature "default" (*) +├── digital-twin-model feature "default" (command-line) (*) +├── async-std feature "attributes" (*) +├── async-std feature "default" (*) +├── env_logger feature "default" (*) +├── samples-common feature "default" (command-line) (*) +├── samples-protobuf-data-access feature "default" (command-line) (*) +├── uuid feature "default" (*) +├── uuid feature "fast-rng" (*) +├── uuid feature "macro-diagnostics" (*) +├── uuid feature "v4" (*) +├── paho-mqtt feature "default" (*) +├── image feature "default" +│ ├── image v0.24.7 +│ │ ├── jpeg-decoder v0.3.0 +│ │ │ └── rayon feature "default" +│ │ │ └── rayon v1.7.0 +│ │ │ ├── either v1.9.0 +│ │ │ └── rayon-core feature "default" +│ │ │ └── rayon-core v1.11.0 +│ │ │ ├── num_cpus feature "default" (*) +│ │ │ ├── crossbeam-utils feature "default" (*) +│ │ │ ├── crossbeam-channel feature "default" (*) +│ │ │ └── crossbeam-deque feature "default" +│ │ │ ├── crossbeam-deque v0.8.3 +│ │ │ │ ├── crossbeam-epoch v0.9.15 +│ │ │ │ │ ├── crossbeam-utils v0.8.16 (*) +│ │ │ │ │ ├── scopeguard v1.2.0 +│ │ │ │ │ ├── cfg-if feature "default" (*) +│ │ │ │ │ └── memoffset feature "default" +│ │ │ │ │ └── memoffset v0.9.0 +│ │ │ │ │ [build-dependencies] +│ │ │ │ │ └── autocfg feature "default" (*) +│ │ │ │ │ [build-dependencies] +│ │ │ │ │ └── autocfg feature "default" (*) +│ │ │ │ ├── crossbeam-utils v0.8.16 (*) +│ │ │ │ └── cfg-if feature "default" (*) +│ │ │ └── crossbeam-deque feature "std" +│ │ │ ├── crossbeam-deque v0.8.3 (*) +│ │ │ ├── crossbeam-utils feature "std" (*) +│ │ │ ├── crossbeam-deque feature "crossbeam-epoch" +│ │ │ │ └── crossbeam-deque v0.8.3 (*) +│ │ │ ├── crossbeam-deque feature "crossbeam-utils" +│ │ │ │ └── crossbeam-deque v0.8.3 (*) +│ │ │ └── crossbeam-epoch feature "std" +│ │ │ ├── crossbeam-epoch v0.9.15 (*) +│ │ │ ├── crossbeam-utils feature "std" (*) +│ │ │ └── crossbeam-epoch feature "alloc" +│ │ │ └── crossbeam-epoch v0.9.15 (*) +│ │ ├── num-rational v0.4.1 +│ │ │ ├── num-integer feature "i128" +│ │ │ │ ├── num-integer v0.1.45 +│ │ │ │ │ └── num-traits v0.2.16 +│ │ │ │ │ [build-dependencies] +│ │ │ │ │ └── autocfg feature "default" (*) +│ │ │ │ │ [build-dependencies] +│ │ │ │ │ └── autocfg feature "default" (*) +│ │ │ │ └── num-traits feature "i128" +│ │ │ │ └── num-traits v0.2.16 (*) +│ │ │ └── num-traits feature "i128" (*) +│ │ │ [build-dependencies] +│ │ │ └── autocfg feature "default" (*) +│ │ ├── bytemuck feature "default" +│ │ │ └── bytemuck v1.13.1 +│ │ ├── bytemuck feature "extern_crate_alloc" +│ │ │ └── bytemuck v1.13.1 +│ │ ├── byteorder feature "default" +│ │ │ ├── byteorder v1.4.3 +│ │ │ └── byteorder feature "std" +│ │ │ └── byteorder v1.4.3 +│ │ ├── color_quant feature "default" +│ │ │ └── color_quant v1.1.0 +│ │ ├── exr feature "default" +│ │ │ └── exr v1.7.0 +│ │ │ ├── smallvec feature "default" (*) +│ │ │ ├── bit_field feature "default" +│ │ │ │ └── bit_field v0.10.2 +│ │ │ ├── flume feature "default" +│ │ │ │ ├── flume v0.10.14 +│ │ │ │ │ ├── futures-core v0.3.28 +│ │ │ │ │ ├── futures-sink v0.3.28 +│ │ │ │ │ ├── pin-project feature "default" (*) +│ │ │ │ │ ├── nanorand feature "default" +│ │ │ │ │ │ ├── nanorand v0.7.0 +│ │ │ │ │ │ │ ├── getrandom feature "default" (*) +│ │ │ │ │ │ │ ├── getrandom feature "js" +│ │ │ │ │ │ │ │ ├── getrandom v0.2.10 (*) +│ │ │ │ │ │ │ │ ├── getrandom feature "js-sys" +│ │ │ │ │ │ │ │ │ └── getrandom v0.2.10 (*) +│ │ │ │ │ │ │ │ └── getrandom feature "wasm-bindgen" +│ │ │ │ │ │ │ │ └── getrandom v0.2.10 (*) +│ │ │ │ │ │ │ └── getrandom feature "rdrand" +│ │ │ │ │ │ │ └── getrandom v0.2.10 (*) +│ │ │ │ │ │ ├── nanorand feature "chacha" +│ │ │ │ │ │ │ └── nanorand v0.7.0 (*) +│ │ │ │ │ │ ├── nanorand feature "pcg64" +│ │ │ │ │ │ │ └── nanorand v0.7.0 (*) +│ │ │ │ │ │ ├── nanorand feature "std" +│ │ │ │ │ │ │ ├── nanorand v0.7.0 (*) +│ │ │ │ │ │ │ └── nanorand feature "alloc" +│ │ │ │ │ │ │ └── nanorand v0.7.0 (*) +│ │ │ │ │ │ ├── nanorand feature "tls" +│ │ │ │ │ │ │ ├── nanorand v0.7.0 (*) +│ │ │ │ │ │ │ ├── nanorand feature "std" (*) +│ │ │ │ │ │ │ └── nanorand feature "wyrand" +│ │ │ │ │ │ │ └── nanorand v0.7.0 (*) +│ │ │ │ │ │ └── nanorand feature "wyrand" (*) +│ │ │ │ │ ├── nanorand feature "getrandom" +│ │ │ │ │ │ └── nanorand v0.7.0 (*) +│ │ │ │ │ ├── spin feature "default" +│ │ │ │ │ │ ├── spin v0.9.8 +│ │ │ │ │ │ │ └── lock_api feature "default" (*) +│ │ │ │ │ │ ├── spin feature "barrier" +│ │ │ │ │ │ │ ├── spin v0.9.8 (*) +│ │ │ │ │ │ │ └── spin feature "mutex" +│ │ │ │ │ │ │ └── spin v0.9.8 (*) +│ │ │ │ │ │ ├── spin feature "lazy" +│ │ │ │ │ │ │ ├── spin v0.9.8 (*) +│ │ │ │ │ │ │ └── spin feature "once" +│ │ │ │ │ │ │ └── spin v0.9.8 (*) +│ │ │ │ │ │ ├── spin feature "lock_api" +│ │ │ │ │ │ │ ├── spin v0.9.8 (*) +│ │ │ │ │ │ │ └── spin feature "lock_api_crate" +│ │ │ │ │ │ │ └── spin v0.9.8 (*) +│ │ │ │ │ │ ├── spin feature "mutex" (*) +│ │ │ │ │ │ ├── spin feature "once" (*) +│ │ │ │ │ │ ├── spin feature "rwlock" +│ │ │ │ │ │ │ └── spin v0.9.8 (*) +│ │ │ │ │ │ └── spin feature "spin_mutex" +│ │ │ │ │ │ ├── spin v0.9.8 (*) +│ │ │ │ │ │ └── spin feature "mutex" (*) +│ │ │ │ │ └── spin feature "mutex" (*) +│ │ │ │ ├── flume feature "async" +│ │ │ │ │ ├── flume v0.10.14 (*) +│ │ │ │ │ ├── flume feature "futures-core" +│ │ │ │ │ │ └── flume v0.10.14 (*) +│ │ │ │ │ ├── flume feature "futures-sink" +│ │ │ │ │ │ └── flume v0.10.14 (*) +│ │ │ │ │ └── flume feature "pin-project" +│ │ │ │ │ └── flume v0.10.14 (*) +│ │ │ │ ├── flume feature "eventual-fairness" +│ │ │ │ │ ├── flume v0.10.14 (*) +│ │ │ │ │ ├── flume feature "async" (*) +│ │ │ │ │ └── flume feature "nanorand" +│ │ │ │ │ └── flume v0.10.14 (*) +│ │ │ │ └── flume feature "select" +│ │ │ │ └── flume v0.10.14 (*) +│ │ │ ├── half feature "default" +│ │ │ │ ├── half v2.2.1 +│ │ │ │ └── half feature "std" +│ │ │ │ ├── half v2.2.1 +│ │ │ │ └── half feature "alloc" +│ │ │ │ └── half v2.2.1 +│ │ │ ├── lebe feature "default" +│ │ │ │ └── lebe v0.5.2 +│ │ │ ├── miniz_oxide feature "default" +│ │ │ │ ├── miniz_oxide v0.7.1 +│ │ │ │ │ ├── adler v1.0.2 +│ │ │ │ │ └── simd-adler32 v0.3.7 +│ │ │ │ └── miniz_oxide feature "with-alloc" +│ │ │ │ └── miniz_oxide v0.7.1 (*) +│ │ │ ├── rayon-core feature "default" (*) +│ │ │ └── zune-inflate feature "zlib" +│ │ │ ├── zune-inflate v0.2.54 +│ │ │ │ └── simd-adler32 v0.3.7 +│ │ │ └── zune-inflate feature "simd-adler32" +│ │ │ └── zune-inflate v0.2.54 (*) +│ │ ├── gif feature "default" +│ │ │ ├── gif v0.12.0 +│ │ │ │ ├── color_quant feature "default" (*) +│ │ │ │ └── weezl feature "default" +│ │ │ │ ├── weezl v0.1.7 +│ │ │ │ └── weezl feature "std" +│ │ │ │ ├── weezl v0.1.7 +│ │ │ │ └── weezl feature "alloc" +│ │ │ │ └── weezl v0.1.7 +│ │ │ ├── gif feature "color_quant" +│ │ │ │ └── gif v0.12.0 (*) +│ │ │ ├── gif feature "raii_no_panic" +│ │ │ │ └── gif v0.12.0 (*) +│ │ │ └── gif feature "std" +│ │ │ └── gif v0.12.0 (*) +│ │ ├── num-traits feature "default" +│ │ │ ├── num-traits v0.2.16 (*) +│ │ │ └── num-traits feature "std" +│ │ │ └── num-traits v0.2.16 (*) +│ │ ├── png feature "default" +│ │ │ └── png v0.17.10 +│ │ │ ├── bitflags feature "default" (*) +│ │ │ ├── miniz_oxide feature "default" (*) +│ │ │ ├── miniz_oxide feature "simd" +│ │ │ │ ├── miniz_oxide v0.7.1 (*) +│ │ │ │ └── miniz_oxide feature "simd-adler32" +│ │ │ │ └── miniz_oxide v0.7.1 (*) +│ │ │ ├── crc32fast feature "default" +│ │ │ │ ├── crc32fast v1.3.2 +│ │ │ │ │ └── cfg-if feature "default" (*) +│ │ │ │ └── crc32fast feature "std" +│ │ │ │ └── crc32fast v1.3.2 (*) +│ │ │ ├── fdeflate feature "default" +│ │ │ │ └── fdeflate v0.3.0 +│ │ │ │ └── simd-adler32 feature "default" +│ │ │ │ ├── simd-adler32 v0.3.7 +│ │ │ │ ├── simd-adler32 feature "const-generics" +│ │ │ │ │ └── simd-adler32 v0.3.7 +│ │ │ │ └── simd-adler32 feature "std" +│ │ │ │ └── simd-adler32 v0.3.7 +│ │ │ └── flate2 feature "default" +│ │ │ ├── flate2 v1.0.27 +│ │ │ │ ├── miniz_oxide feature "with-alloc" (*) +│ │ │ │ └── crc32fast feature "default" (*) +│ │ │ └── flate2 feature "rust_backend" +│ │ │ ├── flate2 v1.0.27 (*) +│ │ │ ├── flate2 feature "any_impl" +│ │ │ │ └── flate2 v1.0.27 (*) +│ │ │ └── flate2 feature "miniz_oxide" +│ │ │ └── flate2 v1.0.27 (*) +│ │ ├── qoi feature "default" +│ │ │ ├── qoi v0.4.1 +│ │ │ │ └── bytemuck feature "default" (*) +│ │ │ └── qoi feature "std" +│ │ │ └── qoi v0.4.1 (*) +│ │ └── tiff feature "default" +│ │ └── tiff v0.9.0 +│ │ ├── jpeg-decoder v0.3.0 (*) +│ │ ├── weezl feature "default" (*) +│ │ └── flate2 feature "default" (*) +│ ├── image feature "bmp" +│ │ └── image v0.24.7 (*) +│ ├── image feature "dds" +│ │ ├── image v0.24.7 (*) +│ │ └── image feature "dxt" +│ │ └── image v0.24.7 (*) +│ ├── image feature "dxt" (*) +│ ├── image feature "farbfeld" +│ │ └── image v0.24.7 (*) +│ ├── image feature "gif" +│ │ └── image v0.24.7 (*) +│ ├── image feature "hdr" +│ │ └── image v0.24.7 (*) +│ ├── image feature "ico" +│ │ ├── image v0.24.7 (*) +│ │ ├── image feature "bmp" (*) +│ │ └── image feature "png" +│ │ └── image v0.24.7 (*) +│ ├── image feature "jpeg" +│ │ └── image v0.24.7 (*) +│ ├── image feature "jpeg_rayon" +│ │ ├── image v0.24.7 (*) +│ │ ├── image feature "jpeg" (*) +│ │ └── jpeg-decoder feature "rayon" +│ │ └── jpeg-decoder v0.3.0 (*) +│ ├── image feature "openexr" +│ │ ├── image v0.24.7 (*) +│ │ └── image feature "exr" +│ │ └── image v0.24.7 (*) +│ ├── image feature "png" (*) +│ ├── image feature "pnm" +│ │ └── image v0.24.7 (*) +│ ├── image feature "qoi" +│ │ └── image v0.24.7 (*) +│ ├── image feature "tga" +│ │ └── image v0.24.7 (*) +│ ├── image feature "tiff" +│ │ └── image v0.24.7 (*) +│ └── image feature "webp" +│ └── image v0.24.7 (*) +└── show-image feature "default" + ├── show-image v0.13.1 + │ ├── indexmap feature "default" (*) + │ ├── futures feature "executor" (*) + │ ├── glam feature "default" + │ │ ├── glam v0.21.3 + │ │ └── glam feature "std" + │ │ └── glam v0.21.3 + │ ├── show-image-macros feature "default" + │ │ └── show-image-macros v0.12.3 (proc-macro) + │ │ ├── proc-macro2 feature "default" (*) + │ │ ├── quote feature "default" (*) + │ │ ├── syn feature "default" (*) + │ │ └── syn feature "full" (*) + │ ├── wgpu feature "default" + │ │ └── wgpu v0.13.1 + │ │ ├── log feature "default" (*) + │ │ ├── parking_lot feature "default" (*) + │ │ ├── smallvec feature "default" (*) + │ │ ├── arrayvec feature "default" + │ │ │ ├── arrayvec v0.7.4 + │ │ │ └── arrayvec feature "std" + │ │ │ └── arrayvec v0.7.4 + │ │ ├── naga feature "default" + │ │ │ └── naga v0.9.0 + │ │ │ ├── thiserror feature "default" (*) + │ │ │ ├── bitflags feature "default" (*) + │ │ │ ├── log feature "default" (*) + │ │ │ ├── indexmap feature "default" (*) + │ │ │ ├── termcolor feature "default" (*) + │ │ │ ├── num-traits feature "default" (*) + │ │ │ ├── bit-set feature "default" + │ │ │ │ ├── bit-set v0.5.3 + │ │ │ │ │ └── bit-vec v0.6.3 + │ │ │ │ └── bit-set feature "std" + │ │ │ │ ├── bit-set v0.5.3 (*) + │ │ │ │ └── bit-vec feature "std" + │ │ │ │ └── bit-vec v0.6.3 + │ │ │ ├── codespan-reporting feature "default" + │ │ │ │ └── codespan-reporting v0.11.1 + │ │ │ │ ├── termcolor feature "default" (*) + │ │ │ │ └── unicode-width feature "default" + │ │ │ │ └── unicode-width v0.1.10 + │ │ │ ├── hexf-parse feature "default" + │ │ │ │ └── hexf-parse v0.2.1 + │ │ │ ├── petgraph feature "default" + │ │ │ │ ├── petgraph v0.6.3 + │ │ │ │ │ ├── fixedbitset v0.4.2 + │ │ │ │ │ ├── indexmap feature "default" (*) + │ │ │ │ │ └── indexmap feature "std" (*) + │ │ │ │ ├── petgraph feature "graphmap" + │ │ │ │ │ └── petgraph v0.6.3 (*) + │ │ │ │ ├── petgraph feature "matrix_graph" + │ │ │ │ │ └── petgraph v0.6.3 (*) + │ │ │ │ └── petgraph feature "stable_graph" + │ │ │ │ └── petgraph v0.6.3 (*) + │ │ │ ├── rustc-hash feature "default" + │ │ │ │ ├── rustc-hash v1.1.0 + │ │ │ │ └── rustc-hash feature "std" + │ │ │ │ └── rustc-hash v1.1.0 + │ │ │ ├── spirv feature "default" + │ │ │ │ └── spirv v0.2.0+1.5.4 + │ │ │ │ ├── num-traits v0.2.16 (*) + │ │ │ │ └── bitflags feature "default" (*) + │ │ │ └── unicode-xid feature "default" + │ │ │ └── unicode-xid v0.2.4 + │ │ ├── raw-window-handle feature "default" + │ │ │ └── raw-window-handle v0.4.3 + │ │ │ └── cty feature "default" + │ │ │ └── cty v0.2.2 + │ │ ├── wgpu-core feature "default" + │ │ │ └── wgpu-core v0.13.2 + │ │ │ ├── profiling v1.0.9 + │ │ │ ├── thiserror feature "default" (*) + │ │ │ ├── bitflags feature "default" (*) + │ │ │ ├── log feature "default" (*) + │ │ │ ├── parking_lot feature "default" (*) + │ │ │ ├── smallvec feature "default" (*) + │ │ │ ├── arrayvec feature "default" (*) + │ │ │ ├── naga feature "default" (*) + │ │ │ ├── naga feature "span" + │ │ │ │ ├── naga v0.9.0 (*) + │ │ │ │ └── naga feature "codespan-reporting" + │ │ │ │ └── naga v0.9.0 (*) + │ │ │ ├── naga feature "validate" + │ │ │ │ └── naga v0.9.0 (*) + │ │ │ ├── naga feature "wgsl-in" + │ │ │ │ ├── naga v0.9.0 (*) + │ │ │ │ ├── naga feature "codespan-reporting" (*) + │ │ │ │ ├── naga feature "hexf-parse" + │ │ │ │ │ └── naga v0.9.0 (*) + │ │ │ │ └── naga feature "unicode-xid" + │ │ │ │ └── naga v0.9.0 (*) + │ │ │ ├── bit-vec feature "default" + │ │ │ │ ├── bit-vec v0.6.3 + │ │ │ │ └── bit-vec feature "std" (*) + │ │ │ ├── codespan-reporting feature "default" (*) + │ │ │ ├── raw-window-handle feature "default" (*) + │ │ │ ├── copyless feature "default" + │ │ │ │ └── copyless v0.1.5 + │ │ │ ├── fxhash feature "default" + │ │ │ │ └── fxhash v0.2.1 + │ │ │ │ └── byteorder feature "default" (*) + │ │ │ ├── wgpu-hal feature "default" + │ │ │ │ └── wgpu-hal v0.13.2 + │ │ │ │ ├── profiling v1.0.9 + │ │ │ │ ├── thiserror feature "default" (*) + │ │ │ │ ├── bitflags feature "default" (*) + │ │ │ │ ├── log feature "default" (*) + │ │ │ │ ├── parking_lot feature "default" (*) + │ │ │ │ ├── arrayvec feature "default" (*) + │ │ │ │ ├── naga feature "default" (*) + │ │ │ │ ├── raw-window-handle feature "default" (*) + │ │ │ │ ├── fxhash feature "default" (*) + │ │ │ │ ├── ash feature "default" + │ │ │ │ │ ├── ash v0.37.3+1.3.251 + │ │ │ │ │ │ └── libloading feature "default" + │ │ │ │ │ │ └── libloading v0.7.4 + │ │ │ │ │ │ └── cfg-if feature "default" (*) + │ │ │ │ │ ├── ash feature "debug" + │ │ │ │ │ │ └── ash v0.37.3+1.3.251 (*) + │ │ │ │ │ └── ash feature "loaded" + │ │ │ │ │ ├── ash v0.37.3+1.3.251 (*) + │ │ │ │ │ └── ash feature "libloading" + │ │ │ │ │ └── ash v0.37.3+1.3.251 (*) + │ │ │ │ ├── libloading feature "default" (*) + │ │ │ │ ├── glow feature "default" + │ │ │ │ │ └── glow v0.11.2 + │ │ │ │ ├── gpu-alloc feature "default" + │ │ │ │ │ ├── gpu-alloc v0.5.4 + │ │ │ │ │ │ ├── bitflags v1.3.2 + │ │ │ │ │ │ └── gpu-alloc-types feature "default" + │ │ │ │ │ │ └── gpu-alloc-types v0.2.0 + │ │ │ │ │ │ └── bitflags v1.3.2 + │ │ │ │ │ └── gpu-alloc feature "std" + │ │ │ │ │ └── gpu-alloc v0.5.4 (*) + │ │ │ │ ├── gpu-descriptor feature "default" + │ │ │ │ │ ├── gpu-descriptor v0.2.3 + │ │ │ │ │ │ ├── bitflags v1.3.2 + │ │ │ │ │ │ ├── hashbrown feature "default" (*) + │ │ │ │ │ │ └── gpu-descriptor-types feature "default" + │ │ │ │ │ │ └── gpu-descriptor-types v0.1.1 + │ │ │ │ │ │ └── bitflags v1.3.2 + │ │ │ │ │ └── gpu-descriptor feature "std" + │ │ │ │ │ └── gpu-descriptor v0.2.3 (*) + │ │ │ │ ├── inplace_it feature "default" + │ │ │ │ │ └── inplace_it v0.3.5 + │ │ │ │ ├── khronos-egl feature "default" + │ │ │ │ │ ├── khronos-egl v4.1.0 + │ │ │ │ │ │ ├── libc feature "default" (*) + │ │ │ │ │ │ └── libloading feature "default" (*) + │ │ │ │ │ └── khronos-egl feature "1_5" + │ │ │ │ │ ├── khronos-egl v4.1.0 (*) + │ │ │ │ │ └── khronos-egl feature "1_4" + │ │ │ │ │ ├── khronos-egl v4.1.0 (*) + │ │ │ │ │ └── khronos-egl feature "1_3" + │ │ │ │ │ ├── khronos-egl v4.1.0 (*) + │ │ │ │ │ └── khronos-egl feature "1_2" + │ │ │ │ │ ├── khronos-egl v4.1.0 (*) + │ │ │ │ │ └── khronos-egl feature "1_1" + │ │ │ │ │ ├── khronos-egl v4.1.0 (*) + │ │ │ │ │ └── khronos-egl feature "1_0" + │ │ │ │ │ └── khronos-egl v4.1.0 (*) + │ │ │ │ ├── khronos-egl feature "dynamic" + │ │ │ │ │ ├── khronos-egl v4.1.0 (*) + │ │ │ │ │ └── khronos-egl feature "libloading" + │ │ │ │ │ └── khronos-egl v4.1.0 (*) + │ │ │ │ ├── renderdoc-sys feature "default" + │ │ │ │ │ └── renderdoc-sys v0.7.1 + │ │ │ │ └── wgpu-types feature "default" + │ │ │ │ └── wgpu-types v0.13.2 + │ │ │ │ └── bitflags feature "default" (*) + │ │ │ ├── wgpu-hal feature "gles" + │ │ │ │ ├── wgpu-hal v0.13.2 (*) + │ │ │ │ ├── naga feature "glsl-out" + │ │ │ │ │ └── naga v0.9.0 (*) + │ │ │ │ ├── wgpu-hal feature "egl" + │ │ │ │ │ └── wgpu-hal v0.13.2 (*) + │ │ │ │ ├── wgpu-hal feature "glow" + │ │ │ │ │ └── wgpu-hal v0.13.2 (*) + │ │ │ │ └── wgpu-hal feature "libloading" + │ │ │ │ └── wgpu-hal v0.13.2 (*) + │ │ │ ├── wgpu-hal feature "renderdoc" + │ │ │ │ ├── wgpu-hal v0.13.2 (*) + │ │ │ │ ├── wgpu-hal feature "libloading" (*) + │ │ │ │ └── wgpu-hal feature "renderdoc-sys" + │ │ │ │ └── wgpu-hal v0.13.2 (*) + │ │ │ ├── wgpu-hal feature "vulkan" + │ │ │ │ ├── wgpu-hal v0.13.2 (*) + │ │ │ │ ├── naga feature "spv-out" + │ │ │ │ │ ├── naga v0.9.0 (*) + │ │ │ │ │ └── naga feature "spirv" + │ │ │ │ │ └── naga v0.9.0 (*) + │ │ │ │ ├── wgpu-hal feature "ash" + │ │ │ │ │ └── wgpu-hal v0.13.2 (*) + │ │ │ │ ├── wgpu-hal feature "gpu-alloc" + │ │ │ │ │ └── wgpu-hal v0.13.2 (*) + │ │ │ │ ├── wgpu-hal feature "gpu-descriptor" + │ │ │ │ │ └── wgpu-hal v0.13.2 (*) + │ │ │ │ ├── wgpu-hal feature "inplace_it" + │ │ │ │ │ └── wgpu-hal v0.13.2 (*) + │ │ │ │ └── wgpu-hal feature "libloading" (*) + │ │ │ └── wgpu-types feature "default" (*) + │ │ │ [build-dependencies] + │ │ │ └── cfg_aliases feature "default" + │ │ │ └── cfg_aliases v0.1.1 + │ │ ├── wgpu-core feature "raw-window-handle" + │ │ │ └── wgpu-core v0.13.2 (*) + │ │ ├── wgpu-hal feature "default" (*) + │ │ └── wgpu-types feature "default" (*) + │ ├── wgpu feature "spirv" + │ │ ├── wgpu v0.13.1 (*) + │ │ ├── wgpu feature "naga" + │ │ │ └── wgpu v0.13.1 (*) + │ │ └── naga feature "spv-in" + │ │ ├── naga v0.9.0 (*) + │ │ ├── naga feature "petgraph" + │ │ │ └── naga v0.9.0 (*) + │ │ └── naga feature "spirv" (*) + │ └── winit feature "default" + │ ├── winit v0.27.5 + │ │ ├── once_cell feature "default" (*) + │ │ ├── bitflags feature "default" (*) + │ │ ├── libc feature "default" (*) + │ │ ├── mio feature "default" + │ │ │ ├── mio v0.8.8 (*) + │ │ │ └── mio feature "log" + │ │ │ └── mio v0.8.8 (*) + │ │ ├── mio feature "os-ext" (*) + │ │ ├── log feature "default" (*) + │ │ ├── percent-encoding feature "default" (*) + │ │ ├── parking_lot feature "default" (*) + │ │ ├── raw-window-handle feature "default" (*) + │ │ ├── instant feature "default" + │ │ │ └── instant v0.1.12 + │ │ │ └── cfg-if feature "default" (*) + │ │ ├── instant feature "wasm-bindgen" + │ │ │ ├── instant v0.1.12 (*) + │ │ │ ├── instant feature "js-sys" + │ │ │ │ └── instant v0.1.12 (*) + │ │ │ ├── instant feature "wasm-bindgen_rs" + │ │ │ │ └── instant v0.1.12 (*) + │ │ │ └── instant feature "web-sys" + │ │ │ └── instant v0.1.12 (*) + │ │ ├── raw-window-handle feature "default" + │ │ │ └── raw-window-handle v0.5.2 + │ │ ├── sctk-adwaita feature "default" + │ │ │ └── sctk-adwaita v0.4.3 + │ │ │ ├── log feature "default" (*) + │ │ │ ├── crossfont feature "default" + │ │ │ │ └── crossfont v0.5.1 + │ │ │ │ ├── libc feature "default" (*) + │ │ │ │ ├── log feature "default" (*) + │ │ │ │ ├── foreign-types feature "default" + │ │ │ │ │ ├── foreign-types v0.5.0 + │ │ │ │ │ │ ├── foreign-types-macros feature "default" + │ │ │ │ │ │ │ └── foreign-types-macros v0.2.3 (proc-macro) + │ │ │ │ │ │ │ ├── proc-macro2 feature "default" (*) + │ │ │ │ │ │ │ ├── quote feature "default" (*) + │ │ │ │ │ │ │ ├── syn feature "default" (*) + │ │ │ │ │ │ │ └── syn feature "full" (*) + │ │ │ │ │ │ └── foreign-types-shared feature "default" + │ │ │ │ │ │ └── foreign-types-shared v0.3.1 + │ │ │ │ │ └── foreign-types feature "std" + │ │ │ │ │ ├── foreign-types v0.5.0 (*) + │ │ │ │ │ └── foreign-types-macros feature "std" + │ │ │ │ │ └── foreign-types-macros v0.2.3 (proc-macro) (*) + │ │ │ │ ├── freetype-rs feature "default" + │ │ │ │ │ └── freetype-rs v0.26.0 + │ │ │ │ │ ├── bitflags feature "default" (*) + │ │ │ │ │ ├── libc feature "default" (*) + │ │ │ │ │ └── freetype-sys feature "default" + │ │ │ │ │ └── freetype-sys v0.13.1 + │ │ │ │ │ └── libc feature "default" (*) + │ │ │ │ │ [build-dependencies] + │ │ │ │ │ ├── cmake feature "default" (*) + │ │ │ │ │ └── pkg-config feature "default" (*) + │ │ │ │ └── servo-fontconfig feature "default" + │ │ │ │ └── servo-fontconfig v0.5.1 + │ │ │ │ ├── libc feature "default" (*) + │ │ │ │ └── servo-fontconfig-sys feature "default" + │ │ │ │ └── servo-fontconfig-sys v5.1.0 + │ │ │ │ ├── freetype-sys feature "default" (*) + │ │ │ │ └── expat-sys feature "default" + │ │ │ │ └── expat-sys v2.1.6 + │ │ │ │ [build-dependencies] + │ │ │ │ ├── cmake feature "default" (*) + │ │ │ │ └── pkg-config feature "default" (*) + │ │ │ │ [build-dependencies] + │ │ │ │ └── pkg-config feature "default" (*) + │ │ │ │ [build-dependencies] + │ │ │ │ └── pkg-config feature "default" (*) + │ │ │ ├── crossfont feature "force_system_fontconfig" + │ │ │ │ ├── crossfont v0.5.1 (*) + │ │ │ │ └── servo-fontconfig feature "force_system_lib" + │ │ │ │ ├── servo-fontconfig v0.5.1 (*) + │ │ │ │ └── servo-fontconfig-sys feature "force_system_lib" + │ │ │ │ └── servo-fontconfig-sys v5.1.0 (*) + │ │ │ ├── smithay-client-toolkit feature "default" + │ │ │ │ ├── smithay-client-toolkit v0.16.0 + │ │ │ │ │ ├── lazy_static feature "default" (*) + │ │ │ │ │ ├── bitflags feature "default" (*) + │ │ │ │ │ ├── log feature "default" (*) + │ │ │ │ │ ├── calloop feature "default" + │ │ │ │ │ │ └── calloop v0.10.6 + │ │ │ │ │ │ ├── thiserror feature "default" (*) + │ │ │ │ │ │ ├── bitflags feature "default" (*) + │ │ │ │ │ │ ├── log feature "default" (*) + │ │ │ │ │ │ ├── nix feature "event" + │ │ │ │ │ │ │ └── nix v0.25.1 + │ │ │ │ │ │ │ ├── cfg-if feature "default" (*) + │ │ │ │ │ │ │ ├── bitflags feature "default" (*) + │ │ │ │ │ │ │ ├── libc feature "default" (*) + │ │ │ │ │ │ │ ├── libc feature "extra_traits" + │ │ │ │ │ │ │ │ └── libc v0.2.147 + │ │ │ │ │ │ │ └── memoffset feature "default" + │ │ │ │ │ │ │ └── memoffset v0.6.5 + │ │ │ │ │ │ │ [build-dependencies] + │ │ │ │ │ │ │ └── autocfg feature "default" (*) + │ │ │ │ │ │ │ [build-dependencies] + │ │ │ │ │ │ │ └── autocfg feature "default" (*) + │ │ │ │ │ │ ├── nix feature "fs" + │ │ │ │ │ │ │ └── nix v0.25.1 (*) + │ │ │ │ │ │ ├── nix feature "signal" + │ │ │ │ │ │ │ ├── nix v0.25.1 (*) + │ │ │ │ │ │ │ └── nix feature "process" + │ │ │ │ │ │ │ └── nix v0.25.1 (*) + │ │ │ │ │ │ ├── nix feature "socket" + │ │ │ │ │ │ │ ├── nix v0.25.1 (*) + │ │ │ │ │ │ │ └── nix feature "memoffset" + │ │ │ │ │ │ │ └── nix v0.25.1 (*) + │ │ │ │ │ │ ├── nix feature "time" + │ │ │ │ │ │ │ └── nix v0.25.1 (*) + │ │ │ │ │ │ ├── slotmap feature "default" + │ │ │ │ │ │ │ ├── slotmap v1.0.6 + │ │ │ │ │ │ │ │ [build-dependencies] + │ │ │ │ │ │ │ │ └── version_check feature "default" (*) + │ │ │ │ │ │ │ └── slotmap feature "std" + │ │ │ │ │ │ │ └── slotmap v1.0.6 (*) + │ │ │ │ │ │ └── vec_map feature "default" + │ │ │ │ │ │ └── vec_map v0.8.2 + │ │ │ │ │ ├── dlib feature "default" + │ │ │ │ │ │ └── dlib v0.5.2 + │ │ │ │ │ │ └── libloading feature "default" + │ │ │ │ │ │ └── libloading v0.8.0 + │ │ │ │ │ │ └── cfg-if feature "default" (*) + │ │ │ │ │ ├── memmap2 feature "default" + │ │ │ │ │ │ └── memmap2 v0.5.10 + │ │ │ │ │ │ └── libc feature "default" (*) + │ │ │ │ │ ├── nix feature "fs" + │ │ │ │ │ │ └── nix v0.24.3 + │ │ │ │ │ │ ├── cfg-if feature "default" (*) + │ │ │ │ │ │ ├── bitflags feature "default" (*) + │ │ │ │ │ │ ├── libc feature "default" (*) + │ │ │ │ │ │ ├── libc feature "extra_traits" (*) + │ │ │ │ │ │ └── memoffset feature "default" (*) + │ │ │ │ │ ├── nix feature "mman" + │ │ │ │ │ │ └── nix v0.24.3 (*) + │ │ │ │ │ ├── wayland-client feature "default" + │ │ │ │ │ │ └── wayland-client v0.29.5 + │ │ │ │ │ │ ├── bitflags feature "default" (*) + │ │ │ │ │ │ ├── libc feature "default" (*) + │ │ │ │ │ │ ├── nix feature "fs" (*) + │ │ │ │ │ │ ├── nix feature "poll" + │ │ │ │ │ │ │ └── nix v0.24.3 (*) + │ │ │ │ │ │ ├── downcast-rs feature "default" + │ │ │ │ │ │ │ ├── downcast-rs v1.2.0 + │ │ │ │ │ │ │ └── downcast-rs feature "std" + │ │ │ │ │ │ │ └── downcast-rs v1.2.0 + │ │ │ │ │ │ ├── scoped-tls feature "default" + │ │ │ │ │ │ │ └── scoped-tls v1.0.1 + │ │ │ │ │ │ ├── wayland-commons feature "default" + │ │ │ │ │ │ │ └── wayland-commons v0.29.5 + │ │ │ │ │ │ │ ├── once_cell feature "default" (*) + │ │ │ │ │ │ │ ├── smallvec feature "default" (*) + │ │ │ │ │ │ │ ├── nix feature "fs" (*) + │ │ │ │ │ │ │ ├── nix feature "socket" + │ │ │ │ │ │ │ │ ├── nix v0.24.3 (*) + │ │ │ │ │ │ │ │ └── nix feature "memoffset" + │ │ │ │ │ │ │ │ └── nix v0.24.3 (*) + │ │ │ │ │ │ │ ├── nix feature "uio" + │ │ │ │ │ │ │ │ └── nix v0.24.3 (*) + │ │ │ │ │ │ │ └── wayland-sys feature "default" + │ │ │ │ │ │ │ └── wayland-sys v0.29.5 + │ │ │ │ │ │ │ ├── lazy_static feature "default" (*) + │ │ │ │ │ │ │ └── dlib feature "default" (*) + │ │ │ │ │ │ │ [build-dependencies] + │ │ │ │ │ │ │ └── pkg-config feature "default" (*) + │ │ │ │ │ │ └── wayland-sys feature "default" (*) + │ │ │ │ │ │ [build-dependencies] + │ │ │ │ │ │ └── wayland-scanner feature "default" + │ │ │ │ │ │ └── wayland-scanner v0.29.5 + │ │ │ │ │ │ ├── proc-macro2 feature "default" (*) + │ │ │ │ │ │ ├── quote feature "default" (*) + │ │ │ │ │ │ └── xml-rs feature "default" + │ │ │ │ │ │ └── xml-rs v0.8.16 + │ │ │ │ │ ├── wayland-cursor feature "default" + │ │ │ │ │ │ └── wayland-cursor v0.29.5 + │ │ │ │ │ │ ├── nix feature "fs" (*) + │ │ │ │ │ │ ├── nix feature "mman" (*) + │ │ │ │ │ │ ├── wayland-client feature "default" (*) + │ │ │ │ │ │ └── xcursor feature "default" + │ │ │ │ │ │ └── xcursor v0.3.4 + │ │ │ │ │ │ └── nom feature "default" (*) + │ │ │ │ │ ├── wayland-protocols feature "client" + │ │ │ │ │ │ ├── wayland-protocols v0.29.5 + │ │ │ │ │ │ │ ├── bitflags feature "default" (*) + │ │ │ │ │ │ │ ├── wayland-client feature "default" (*) + │ │ │ │ │ │ │ └── wayland-commons feature "default" (*) + │ │ │ │ │ │ │ [build-dependencies] + │ │ │ │ │ │ │ └── wayland-scanner feature "default" (*) + │ │ │ │ │ │ └── wayland-protocols feature "wayland-client" + │ │ │ │ │ │ └── wayland-protocols v0.29.5 (*) + │ │ │ │ │ ├── wayland-protocols feature "default" + │ │ │ │ │ │ └── wayland-protocols v0.29.5 (*) + │ │ │ │ │ └── wayland-protocols feature "unstable_protocols" + │ │ │ │ │ └── wayland-protocols v0.29.5 (*) + │ │ │ │ │ [build-dependencies] + │ │ │ │ │ └── pkg-config feature "default" (*) + │ │ │ │ ├── smithay-client-toolkit feature "calloop" + │ │ │ │ │ └── smithay-client-toolkit v0.16.0 (*) + │ │ │ │ └── smithay-client-toolkit feature "dlopen" + │ │ │ │ ├── smithay-client-toolkit v0.16.0 (*) + │ │ │ │ └── wayland-client feature "dlopen" + │ │ │ │ ├── wayland-client v0.29.5 (*) + │ │ │ │ ├── wayland-client feature "use_system_lib" + │ │ │ │ │ ├── wayland-client v0.29.5 (*) + │ │ │ │ │ ├── wayland-client feature "scoped-tls" + │ │ │ │ │ │ └── wayland-client v0.29.5 (*) + │ │ │ │ │ └── wayland-sys feature "client" + │ │ │ │ │ ├── wayland-sys v0.29.5 (*) + │ │ │ │ │ └── wayland-sys feature "dlib" + │ │ │ │ │ └── wayland-sys v0.29.5 (*) + │ │ │ │ └── wayland-sys feature "dlopen" + │ │ │ │ ├── wayland-sys v0.29.5 (*) + │ │ │ │ ├── wayland-sys feature "dlib" (*) + │ │ │ │ └── wayland-sys feature "lazy_static" + │ │ │ │ └── wayland-sys v0.29.5 (*) + │ │ │ ├── tiny-skia feature "default" + │ │ │ │ ├── tiny-skia v0.7.0 + │ │ │ │ │ ├── arrayvec v0.5.2 + │ │ │ │ │ ├── tiny-skia-path v0.7.0 + │ │ │ │ │ │ ├── bytemuck feature "default" (*) + │ │ │ │ │ │ └── arrayref feature "default" + │ │ │ │ │ │ └── arrayref v0.3.7 + │ │ │ │ │ ├── cfg-if feature "default" (*) + │ │ │ │ │ ├── bytemuck feature "default" (*) + │ │ │ │ │ ├── png feature "default" (*) + │ │ │ │ │ ├── arrayref feature "default" (*) + │ │ │ │ │ ├── safe_arch feature "bytemuck" + │ │ │ │ │ │ └── safe_arch v0.5.2 + │ │ │ │ │ │ └── bytemuck feature "default" (*) + │ │ │ │ │ └── safe_arch feature "default" + │ │ │ │ │ └── safe_arch v0.5.2 (*) + │ │ │ │ ├── tiny-skia feature "png-format" + │ │ │ │ │ ├── tiny-skia v0.7.0 (*) + │ │ │ │ │ ├── tiny-skia feature "png" + │ │ │ │ │ │ └── tiny-skia v0.7.0 (*) + │ │ │ │ │ └── tiny-skia feature "std" + │ │ │ │ │ ├── tiny-skia v0.7.0 (*) + │ │ │ │ │ └── tiny-skia-path feature "std" + │ │ │ │ │ └── tiny-skia-path v0.7.0 (*) + │ │ │ │ ├── tiny-skia feature "simd" + │ │ │ │ │ ├── tiny-skia v0.7.0 (*) + │ │ │ │ │ └── tiny-skia feature "safe_arch" + │ │ │ │ │ └── tiny-skia v0.7.0 (*) + │ │ │ │ └── tiny-skia feature "std" (*) + │ │ │ ├── tiny-skia feature "simd" (*) + │ │ │ └── tiny-skia feature "std" (*) + │ │ ├── smithay-client-toolkit feature "calloop" (*) + │ │ ├── wayland-client feature "use_system_lib" (*) + │ │ ├── wayland-protocols feature "default" (*) + │ │ ├── wayland-protocols feature "staging_protocols" + │ │ │ └── wayland-protocols v0.29.5 (*) + │ │ └── x11-dl feature "default" + │ │ └── x11-dl v2.21.0 + │ │ ├── once_cell feature "default" (*) + │ │ └── libc feature "default" (*) + │ │ [build-dependencies] + │ │ └── pkg-config feature "default" (*) + │ ├── winit feature "wayland" + │ │ ├── winit v0.27.5 (*) + │ │ ├── winit feature "sctk" + │ │ │ └── winit v0.27.5 (*) + │ │ ├── winit feature "wayland-client" + │ │ │ └── winit v0.27.5 (*) + │ │ └── winit feature "wayland-protocols" + │ │ └── winit v0.27.5 (*) + │ ├── winit feature "wayland-csd-adwaita" + │ │ ├── winit v0.27.5 (*) + │ │ ├── winit feature "sctk-adwaita" + │ │ │ └── winit v0.27.5 (*) + │ │ └── sctk-adwaita feature "title" + │ │ ├── sctk-adwaita v0.4.3 (*) + │ │ └── sctk-adwaita feature "crossfont" + │ │ └── sctk-adwaita v0.4.3 (*) + │ ├── winit feature "wayland-dlopen" + │ │ ├── winit v0.27.5 (*) + │ │ ├── winit feature "sctk" (*) + │ │ ├── winit feature "wayland-client" (*) + │ │ ├── smithay-client-toolkit feature "dlopen" (*) + │ │ └── wayland-client feature "dlopen" (*) + │ └── winit feature "x11" + │ ├── winit v0.27.5 (*) + │ ├── winit feature "mio" + │ │ └── winit v0.27.5 (*) + │ ├── winit feature "parking_lot" + │ │ └── winit v0.27.5 (*) + │ ├── winit feature "percent-encoding" + │ │ └── winit v0.27.5 (*) + │ └── winit feature "x11-dl" + │ └── winit v0.27.5 (*) + │ [build-dependencies] + │ └── rustc_version feature "default" + │ └── rustc_version v0.4.0 + │ └── semver feature "default" + │ ├── semver v1.0.18 + │ └── semver feature "std" + │ └── semver v1.0.18 + └── show-image feature "macros" + ├── show-image v0.13.1 (*) + └── show-image feature "show-image-macros" + └── show-image v0.13.1 (*) +[build-dependencies] +└── tonic-build feature "default" (*) diff --git a/tools/dotnet_append_to_notice.sh b/tools/dotnet_append_to_notice.sh new file mode 100755 index 00000000..fa145723 --- /dev/null +++ b/tools/dotnet_append_to_notice.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +set -e + +# Check if the correct number of arguments are provided +if [ "$#" -ne 2 ]; then + echo "Usage: $0 path_to_markdown_file path_to_json_file" + exit 1 +fi + +# Assign arguments to variables for clarity +markdown_file="$1" +json_file="$2" + +# Check if the markdown file exists +if [ ! -f "$markdown_file" ]; then + echo "Error: markdown file '$markdown_file' not found" + exit 1 +fi + +# Check if the JSON file exists +if [ ! -f "$json_file" ]; then + echo "Error: JSON file '$json_file' not found" + exit 1 +fi + +# Append header to markdown file +echo -e "\n\n# .NET Third Party Licenses\nThe following lists the licenses of the .NET projects used.\n" >> "$markdown_file" + +# Read JSON file and append information to markdown file +while read -r line; do + # Extract values from JSON object + license_type=$(echo "$line" | jq -r '.LicenseType') + package_name=$(echo "$line" | jq -r '.PackageName') + package_version=$(echo "$line" | jq -r '.PackageVersion') + package_url=$(echo "$line" | jq -r '.PackageUrl') + license_description=$(echo "$line" | jq -r '.LicenseDescription') + + # Append information to markdown file in specified format + echo "### $license_type" >> "$markdown_file" + echo -e "\n#### Used by\n" >> "$markdown_file" + echo "- [$package_name]( $package_url ) $package_version" >> "$markdown_file" + echo -e "\n#### License\n" >> "$markdown_file" + echo '```text' >> "$markdown_file" + echo -e "$license_description" >> "$markdown_file" + echo '```' >> "$markdown_file" +done < <(jq -c '.[]' "$json_file") + +echo -e "\n## Disclaimer" >> "$markdown_file" +echo -e " +This .NET Third Party Licenses list has been generated with [nuget-license](https://github.com/tomchavakis/nuget-license), \ +licensed under [Apache License 2.0](https://github.com/tomchavakis/nuget-license/blob/master/LICENSE)" >> "$markdown_file" + +exit 0 \ No newline at end of file diff --git a/tools/dotnet_get_licenses.sh b/tools/dotnet_get_licenses.sh new file mode 100755 index 00000000..f580156d --- /dev/null +++ b/tools/dotnet_get_licenses.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +set -e + +# Check if the correct number of arguments are provided +if [ "$#" -ne 2 ]; then + echo "Usage: $0 path_to_json_file path_to_text_files_directory" + exit 1 +fi + +# Assign arguments to variables for clarity +json_file="$1" +text_files_dir="$2" + +# Check if the JSON file exists +if [ ! -f "$json_file" ]; then + echo "Error: JSON file '$json_file' not found" + exit 1 +fi + +# Check if the text files directory exists +if [ ! -d "$text_files_dir" ]; then + echo "Error: text files directory '$text_files_dir' not found" + exit 1 +fi + +# Create a temporary file to store the updated JSON +temp_file=$(mktemp) + +# Read JSON file and update elements with LicenseDescription field +while read -r line; do + # Extract values from JSON object + package_name=$(echo "$line" | jq -r '.PackageName') + package_version=$(echo "$line" | jq -r '.PackageVersion') + + # Construct path to license description text file + license_description_file="${text_files_dir}/${package_name}_${package_version}.txt" + + # Check if the license description text file exists + if [ ! -f "$license_description_file" ]; then + echo "Error: license description text file '$license_description_file' not found" + exit 1 + fi + + # Read license description text file and add LicenseDescription field to JSON object + license_description=$(cat "$license_description_file") + updated_json=$(echo "$line" | jq --arg desc "$license_description" '. + {LicenseDescription: $desc}') + + # Write updated JSON object to temporary file + echo "$updated_json" >> "$temp_file" +done < <(jq -c '.[]' "$json_file") + +# Overwrite original JSON file with updated JSON from temporary file +jq -s '.' "$temp_file" > "$json_file" + +# Remove temporary file +rm "$temp_file" + +exit 0 \ No newline at end of file diff --git a/tools/dotnet_notice_generation.sh b/tools/dotnet_notice_generation.sh new file mode 100755 index 00000000..a1f98875 --- /dev/null +++ b/tools/dotnet_notice_generation.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT license. +# SPDX-License-Identifier: MIT + +set -e + +cd "$(dirname "$0")/.." + +# Check if the correct number of argments are passed +if [ "$#" -lt 3 ] ; then + echo "Usage: $0 " + exit 1 +fi + +# Assign notice_file_path and dotnet_directory to arguments +notice_file_path="$1" +dotnet_directory="$2" +license_url_to_license_mappings="$3" + +# Check if the notice file exists +if [ ! -f "$notice_file_path" ]; then + echo "Error: Notice file '$notice_file_path' not found" + exit 1 +fi + +if ! dotnet tool list --global | grep -q 'dotnet-project-licenses'; then + dotnet tool install --global dotnet-project-licenses +fi + +dotnet_licenses_output_directory="$dotnet_directory/dotnet_licenses_output" +mkdir -p "$dotnet_licenses_output_directory" +echo "Getting the .NET Third Party licenses" + +dotnet-project-licenses -i $dotnet_directory -o -f "$dotnet_licenses_output_directory" -u --json -e -c \ + --licenseurl-to-license-mappings "$license_url_to_license_mappings" + +./tools/dotnet_get_licenses.sh "$dotnet_licenses_output_directory/licenses.json" "$dotnet_directory/dotnet_licenses_output" +./tools/dotnet_append_to_notice.sh "$notice_file_path" "$dotnet_licenses_output_directory/licenses.json" + +rm -r "$dotnet_licenses_output_directory" + +exit 0 \ No newline at end of file diff --git a/tools/notice_generation.sh b/tools/notice_generation.sh index 97cdb56b..54e0aa2a 100755 --- a/tools/notice_generation.sh +++ b/tools/notice_generation.sh @@ -36,6 +36,10 @@ NOTICE_FILENAME="NOTICE" echo "Running cargo-about for NOTICE file generation..." cargo about generate --workspace devops/cg/about.hbs --config devops/cg/about.toml > $NOTICE_FILENAME +DOTNET_SRC_DIRECTORY="dtdl-tools/" +echo "Appending .NET Third Party licenses to $NOTICE_FILENAME" +./tools/dotnet_notice_generation.sh $NOTICE_FILENAME $CLOUD_CONNECTORS_AZURE_DIRECTORY ./devops/cg/license_url_to_type.json + if [ -z "$(git diff --name-only $NOTICE_FILENAME)" ] then echo "File not changed" From d8c1846e73a2c4bab6342802f41914781b8fa19b Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Fri, 6 Oct 2023 11:56:57 -0700 Subject: [PATCH 02/28] Removed DTDL Parser --- tmp.out | 2482 ------------------------------------ tools/notice_generation.sh | 2 +- 2 files changed, 1 insertion(+), 2483 deletions(-) delete mode 100644 tmp.out diff --git a/tmp.out b/tmp.out deleted file mode 100644 index fdaac18b..00000000 --- a/tmp.out +++ /dev/null @@ -1,2482 +0,0 @@ -common v0.1.0 (/home/ashbeitz/repos/ibeji/core/common) -├── bytes feature "default" -│ ├── bytes v1.4.0 -│ └── bytes feature "std" -│ └── bytes v1.4.0 -├── config feature "default" -│ ├── config v0.13.3 -│ │ ├── async-trait feature "default" -│ │ │ └── async-trait v0.1.72 (proc-macro) -│ │ │ ├── proc-macro2 feature "default" -│ │ │ │ ├── proc-macro2 v1.0.66 -│ │ │ │ │ └── unicode-ident feature "default" -│ │ │ │ │ └── unicode-ident v1.0.11 -│ │ │ │ └── proc-macro2 feature "proc-macro" -│ │ │ │ └── proc-macro2 v1.0.66 (*) -│ │ │ ├── quote feature "default" -│ │ │ │ ├── quote v1.0.32 -│ │ │ │ │ └── proc-macro2 v1.0.66 (*) -│ │ │ │ └── quote feature "proc-macro" -│ │ │ │ ├── quote v1.0.32 (*) -│ │ │ │ └── proc-macro2 feature "proc-macro" (*) -│ │ │ ├── syn feature "default" -│ │ │ │ ├── syn v2.0.27 -│ │ │ │ │ ├── proc-macro2 v1.0.66 (*) -│ │ │ │ │ ├── quote v1.0.32 (*) -│ │ │ │ │ └── unicode-ident feature "default" (*) -│ │ │ │ ├── syn feature "clone-impls" -│ │ │ │ │ └── syn v2.0.27 (*) -│ │ │ │ ├── syn feature "derive" -│ │ │ │ │ └── syn v2.0.27 (*) -│ │ │ │ ├── syn feature "parsing" -│ │ │ │ │ └── syn v2.0.27 (*) -│ │ │ │ ├── syn feature "printing" -│ │ │ │ │ ├── syn v2.0.27 (*) -│ │ │ │ │ └── syn feature "quote" -│ │ │ │ │ └── syn v2.0.27 (*) -│ │ │ │ └── syn feature "proc-macro" -│ │ │ │ ├── syn v2.0.27 (*) -│ │ │ │ ├── proc-macro2 feature "proc-macro" (*) -│ │ │ │ ├── quote feature "proc-macro" (*) -│ │ │ │ └── syn feature "quote" (*) -│ │ │ ├── syn feature "full" -│ │ │ │ └── syn v2.0.27 (*) -│ │ │ └── syn feature "visit-mut" -│ │ │ └── syn v2.0.27 (*) -│ │ ├── json5 feature "default" -│ │ │ └── json5 v0.4.1 -│ │ │ ├── pest feature "default" -│ │ │ │ ├── pest v2.7.1 -│ │ │ │ │ ├── ucd-trie v0.1.6 -│ │ │ │ │ └── thiserror feature "default" -│ │ │ │ │ └── thiserror v1.0.44 -│ │ │ │ │ └── thiserror-impl feature "default" -│ │ │ │ │ └── thiserror-impl v1.0.44 (proc-macro) -│ │ │ │ │ ├── proc-macro2 feature "default" (*) -│ │ │ │ │ ├── quote feature "default" (*) -│ │ │ │ │ └── syn feature "default" (*) -│ │ │ │ └── pest feature "std" -│ │ │ │ ├── pest v2.7.1 (*) -│ │ │ │ └── ucd-trie feature "std" -│ │ │ │ └── ucd-trie v0.1.6 -│ │ │ ├── pest_derive feature "default" -│ │ │ │ ├── pest_derive v2.7.1 (proc-macro) -│ │ │ │ │ ├── pest v2.7.1 (*) -│ │ │ │ │ └── pest_generator v2.7.1 -│ │ │ │ │ ├── pest v2.7.1 (*) -│ │ │ │ │ ├── proc-macro2 feature "default" (*) -│ │ │ │ │ ├── quote feature "default" (*) -│ │ │ │ │ ├── syn feature "default" (*) -│ │ │ │ │ └── pest_meta feature "default" -│ │ │ │ │ └── pest_meta v2.7.1 -│ │ │ │ │ ├── pest feature "default" (*) -│ │ │ │ │ └── once_cell feature "default" -│ │ │ │ │ ├── once_cell v1.18.0 -│ │ │ │ │ └── once_cell feature "std" -│ │ │ │ │ ├── once_cell v1.18.0 -│ │ │ │ │ └── once_cell feature "alloc" -│ │ │ │ │ ├── once_cell v1.18.0 -│ │ │ │ │ └── once_cell feature "race" -│ │ │ │ │ └── once_cell v1.18.0 -│ │ │ │ │ [build-dependencies] -│ │ │ │ │ └── sha2 v0.10.7 -│ │ │ │ │ ├── cfg-if feature "default" -│ │ │ │ │ │ └── cfg-if v1.0.0 -│ │ │ │ │ ├── cpufeatures feature "default" -│ │ │ │ │ │ └── cpufeatures v0.2.9 -│ │ │ │ │ └── digest feature "default" -│ │ │ │ │ ├── digest v0.10.7 -│ │ │ │ │ │ ├── block-buffer feature "default" -│ │ │ │ │ │ │ └── block-buffer v0.10.4 -│ │ │ │ │ │ │ └── generic-array feature "default" -│ │ │ │ │ │ │ └── generic-array v0.14.7 -│ │ │ │ │ │ │ └── typenum feature "default" -│ │ │ │ │ │ │ └── typenum v1.16.0 -│ │ │ │ │ │ │ [build-dependencies] -│ │ │ │ │ │ │ └── version_check feature "default" -│ │ │ │ │ │ │ └── version_check v0.9.4 -│ │ │ │ │ │ └── crypto-common feature "default" -│ │ │ │ │ │ └── crypto-common v0.1.6 -│ │ │ │ │ │ ├── generic-array feature "default" (*) -│ │ │ │ │ │ ├── generic-array feature "more_lengths" -│ │ │ │ │ │ │ └── generic-array v0.14.7 (*) -│ │ │ │ │ │ └── typenum feature "default" (*) -│ │ │ │ │ └── digest feature "core-api" -│ │ │ │ │ ├── digest v0.10.7 (*) -│ │ │ │ │ └── digest feature "block-buffer" -│ │ │ │ │ └── digest v0.10.7 (*) -│ │ │ │ └── pest_derive feature "std" -│ │ │ │ ├── pest_derive v2.7.1 (proc-macro) (*) -│ │ │ │ ├── pest feature "std" (*) -│ │ │ │ └── pest_generator feature "std" -│ │ │ │ ├── pest_generator v2.7.1 (*) -│ │ │ │ └── pest feature "std" (*) -│ │ │ └── serde feature "default" -│ │ │ ├── serde v1.0.177 -│ │ │ │ └── serde_derive feature "default" -│ │ │ │ └── serde_derive v1.0.177 (proc-macro) -│ │ │ └── serde feature "std" -│ │ │ └── serde v1.0.177 (*) -│ │ ├── serde feature "default" (*) -│ │ ├── lazy_static feature "default" -│ │ │ └── lazy_static v1.4.0 -│ │ ├── nom feature "default" -│ │ │ ├── nom v7.1.3 -│ │ │ │ ├── memchr v2.5.0 -│ │ │ │ └── minimal-lexical v0.2.1 -│ │ │ └── nom feature "std" -│ │ │ ├── nom v7.1.3 (*) -│ │ │ ├── nom feature "alloc" -│ │ │ │ └── nom v7.1.3 (*) -│ │ │ ├── memchr feature "std" -│ │ │ │ └── memchr v2.5.0 -│ │ │ └── minimal-lexical feature "std" -│ │ │ └── minimal-lexical v0.2.1 -│ │ ├── pathdiff feature "default" -│ │ │ └── pathdiff v0.2.1 -│ │ ├── ron feature "default" -│ │ │ └── ron v0.7.1 -│ │ │ ├── serde feature "default" (*) -│ │ │ ├── serde feature "serde_derive" -│ │ │ │ └── serde v1.0.177 (*) -│ │ │ ├── base64 feature "default" -│ │ │ │ ├── base64 v0.13.1 -│ │ │ │ └── base64 feature "std" -│ │ │ │ └── base64 v0.13.1 -│ │ │ └── bitflags feature "default" -│ │ │ └── bitflags v1.3.2 -│ │ ├── rust-ini feature "default" -│ │ │ └── rust-ini v0.18.0 -│ │ │ ├── cfg-if feature "default" (*) -│ │ │ └── ordered-multimap feature "default" -│ │ │ └── ordered-multimap v0.4.3 -│ │ │ ├── dlv-list feature "default" -│ │ │ │ └── dlv-list v0.3.0 -│ │ │ └── hashbrown feature "default" -│ │ │ ├── hashbrown v0.12.3 -│ │ │ │ └── ahash v0.7.6 -│ │ │ │ ├── once_cell feature "alloc" (*) -│ │ │ │ └── getrandom feature "default" -│ │ │ │ └── getrandom v0.2.10 -│ │ │ │ ├── libc v0.2.147 -│ │ │ │ └── cfg-if feature "default" (*) -│ │ │ │ [build-dependencies] -│ │ │ │ └── version_check feature "default" (*) -│ │ │ ├── hashbrown feature "ahash" -│ │ │ │ └── hashbrown v0.12.3 (*) -│ │ │ └── hashbrown feature "inline-more" -│ │ │ └── hashbrown v0.12.3 (*) -│ │ ├── serde_json feature "default" -│ │ │ ├── serde_json v1.0.104 -│ │ │ │ ├── serde v1.0.177 (*) -│ │ │ │ ├── itoa feature "default" -│ │ │ │ │ └── itoa v1.0.9 -│ │ │ │ └── ryu feature "default" -│ │ │ │ └── ryu v1.0.15 -│ │ │ └── serde_json feature "std" -│ │ │ ├── serde_json v1.0.104 (*) -│ │ │ └── serde feature "std" (*) -│ │ ├── toml feature "default" -│ │ │ └── toml v0.5.11 -│ │ │ └── serde feature "default" (*) -│ │ └── yaml-rust feature "default" -│ │ └── yaml-rust v0.4.5 -│ │ └── linked-hash-map feature "default" -│ │ └── linked-hash-map v0.5.6 -│ ├── config feature "ini" -│ │ ├── config v0.13.3 (*) -│ │ └── config feature "rust-ini" -│ │ └── config v0.13.3 (*) -│ ├── config feature "json" -│ │ ├── config v0.13.3 (*) -│ │ └── config feature "serde_json" -│ │ └── config v0.13.3 (*) -│ ├── config feature "json5" -│ │ ├── config v0.13.3 (*) -│ │ └── config feature "json5_rs" -│ │ └── config v0.13.3 (*) -│ ├── config feature "ron" -│ │ └── config v0.13.3 (*) -│ ├── config feature "toml" -│ │ └── config v0.13.3 (*) -│ └── config feature "yaml" -│ ├── config v0.13.3 (*) -│ └── config feature "yaml-rust" -│ └── config v0.13.3 (*) -├── serde feature "default" (*) -├── serde feature "derive" -│ ├── serde v1.0.177 (*) -│ └── serde feature "serde_derive" (*) -├── serde_derive feature "default" (*) -├── core-protobuf-data-access feature "default" (command-line) -│ └── core-protobuf-data-access v0.1.0 (/home/ashbeitz/repos/ibeji/core/protobuf_data_access) -│ ├── serde feature "default" (*) -│ ├── serde feature "derive" (*) -│ ├── prost feature "default" -│ │ ├── prost v0.12.1 -│ │ │ ├── bytes v1.4.0 -│ │ │ └── prost-derive feature "default" -│ │ │ └── prost-derive v0.12.1 (proc-macro) -│ │ │ ├── proc-macro2 feature "default" (*) -│ │ │ ├── quote feature "default" (*) -│ │ │ ├── syn feature "default" (*) -│ │ │ ├── syn feature "extra-traits" -│ │ │ │ └── syn v2.0.27 (*) -│ │ │ ├── anyhow feature "default" -│ │ │ │ ├── anyhow v1.0.72 -│ │ │ │ └── anyhow feature "std" -│ │ │ │ └── anyhow v1.0.72 -│ │ │ └── itertools feature "use_alloc" -│ │ │ └── itertools v0.10.5 -│ │ │ └── either v1.9.0 -│ │ ├── prost feature "prost-derive" -│ │ │ └── prost v0.12.1 (*) -│ │ └── prost feature "std" -│ │ └── prost v0.12.1 (*) -│ ├── prost-types feature "default" -│ │ ├── prost-types v0.12.1 -│ │ │ └── prost feature "prost-derive" (*) -│ │ └── prost-types feature "std" -│ │ ├── prost-types v0.12.1 (*) -│ │ └── prost feature "std" (*) -│ ├── tokio feature "default" -│ │ └── tokio v1.29.1 -│ │ ├── mio v0.8.8 -│ │ │ ├── libc feature "default" -│ │ │ │ ├── libc v0.2.147 -│ │ │ │ └── libc feature "std" -│ │ │ │ └── libc v0.2.147 -│ │ │ └── log feature "default" -│ │ │ └── log v0.4.19 -│ │ │ └── value-bag v1.4.1 -│ │ ├── bytes feature "default" (*) -│ │ ├── libc feature "default" (*) -│ │ ├── num_cpus feature "default" -│ │ │ └── num_cpus v1.16.0 -│ │ │ └── libc feature "default" (*) -│ │ ├── pin-project-lite feature "default" -│ │ │ └── pin-project-lite v0.2.10 -│ │ ├── signal-hook-registry feature "default" -│ │ │ └── signal-hook-registry v1.4.1 -│ │ │ └── libc feature "default" (*) -│ │ ├── socket2 feature "all" -│ │ │ └── socket2 v0.4.9 -│ │ │ └── libc feature "default" (*) -│ │ ├── socket2 feature "default" -│ │ │ └── socket2 v0.4.9 (*) -│ │ └── tokio-macros feature "default" -│ │ └── tokio-macros v2.1.0 (proc-macro) -│ │ ├── proc-macro2 feature "default" (*) -│ │ ├── quote feature "default" (*) -│ │ ├── syn feature "default" (*) -│ │ └── syn feature "full" (*) -│ │ [build-dependencies] -│ │ └── autocfg feature "default" -│ │ └── autocfg v1.1.0 -│ ├── tokio feature "macros" -│ │ ├── tokio v1.29.1 (*) -│ │ └── tokio feature "tokio-macros" -│ │ └── tokio v1.29.1 (*) -│ ├── tokio feature "rt-multi-thread" -│ │ ├── tokio v1.29.1 (*) -│ │ ├── tokio feature "num_cpus" -│ │ │ └── tokio v1.29.1 (*) -│ │ └── tokio feature "rt" -│ │ └── tokio v1.29.1 (*) -│ └── tonic feature "default" -│ ├── tonic v0.10.0 -│ │ ├── axum v0.6.19 -│ │ │ ├── bytes feature "default" (*) -│ │ │ ├── async-trait feature "default" (*) -│ │ │ ├── serde feature "default" (*) -│ │ │ ├── memchr feature "default" -│ │ │ │ ├── memchr v2.5.0 -│ │ │ │ └── memchr feature "std" (*) -│ │ │ ├── bitflags feature "default" (*) -│ │ │ ├── itoa feature "default" (*) -│ │ │ ├── pin-project-lite feature "default" (*) -│ │ │ ├── axum-core feature "default" -│ │ │ │ └── axum-core v0.3.4 -│ │ │ │ ├── bytes feature "default" (*) -│ │ │ │ ├── async-trait feature "default" (*) -│ │ │ │ ├── futures-util feature "alloc" -│ │ │ │ │ ├── futures-util v0.3.28 -│ │ │ │ │ │ ├── futures-core v0.3.28 -│ │ │ │ │ │ ├── futures-macro v0.3.28 (proc-macro) -│ │ │ │ │ │ │ ├── proc-macro2 feature "default" (*) -│ │ │ │ │ │ │ ├── quote feature "default" (*) -│ │ │ │ │ │ │ ├── syn feature "default" (*) -│ │ │ │ │ │ │ └── syn feature "full" (*) -│ │ │ │ │ │ ├── futures-sink v0.3.28 -│ │ │ │ │ │ ├── futures-task v0.3.28 -│ │ │ │ │ │ ├── memchr feature "default" (*) -│ │ │ │ │ │ ├── pin-project-lite feature "default" (*) -│ │ │ │ │ │ ├── futures-channel feature "std" -│ │ │ │ │ │ │ ├── futures-channel v0.3.28 -│ │ │ │ │ │ │ │ ├── futures-core v0.3.28 -│ │ │ │ │ │ │ │ └── futures-sink v0.3.28 -│ │ │ │ │ │ │ ├── futures-core feature "std" -│ │ │ │ │ │ │ │ ├── futures-core v0.3.28 -│ │ │ │ │ │ │ │ └── futures-core feature "alloc" -│ │ │ │ │ │ │ │ └── futures-core v0.3.28 -│ │ │ │ │ │ │ └── futures-channel feature "alloc" -│ │ │ │ │ │ │ ├── futures-channel v0.3.28 (*) -│ │ │ │ │ │ │ └── futures-core feature "alloc" (*) -│ │ │ │ │ │ ├── futures-io feature "std" -│ │ │ │ │ │ │ └── futures-io v0.3.28 -│ │ │ │ │ │ ├── pin-utils feature "default" -│ │ │ │ │ │ │ └── pin-utils v0.1.0 -│ │ │ │ │ │ └── slab feature "default" -│ │ │ │ │ │ ├── slab v0.4.8 -│ │ │ │ │ │ │ [build-dependencies] -│ │ │ │ │ │ │ └── autocfg feature "default" (*) -│ │ │ │ │ │ └── slab feature "std" -│ │ │ │ │ │ └── slab v0.4.8 (*) -│ │ │ │ │ ├── futures-core feature "alloc" (*) -│ │ │ │ │ └── futures-task feature "alloc" -│ │ │ │ │ └── futures-task v0.3.28 -│ │ │ │ ├── http feature "default" -│ │ │ │ │ └── http v0.2.9 -│ │ │ │ │ ├── bytes feature "default" (*) -│ │ │ │ │ ├── itoa feature "default" (*) -│ │ │ │ │ └── fnv feature "default" -│ │ │ │ │ ├── fnv v1.0.7 -│ │ │ │ │ └── fnv feature "std" -│ │ │ │ │ └── fnv v1.0.7 -│ │ │ │ ├── http-body feature "default" -│ │ │ │ │ └── http-body v0.4.5 -│ │ │ │ │ ├── bytes feature "default" (*) -│ │ │ │ │ ├── pin-project-lite feature "default" (*) -│ │ │ │ │ └── http feature "default" (*) -│ │ │ │ ├── mime feature "default" -│ │ │ │ │ └── mime v0.3.17 -│ │ │ │ ├── tower-layer feature "default" -│ │ │ │ │ └── tower-layer v0.3.2 -│ │ │ │ └── tower-service feature "default" -│ │ │ │ └── tower-service v0.3.2 -│ │ │ │ [build-dependencies] -│ │ │ │ └── rustversion feature "default" -│ │ │ │ └── rustversion v1.0.14 (proc-macro) -│ │ │ ├── futures-util feature "alloc" (*) -│ │ │ ├── http feature "default" (*) -│ │ │ ├── http-body feature "default" (*) -│ │ │ ├── mime feature "default" (*) -│ │ │ ├── tower-layer feature "default" (*) -│ │ │ ├── tower-service feature "default" (*) -│ │ │ ├── hyper feature "default" -│ │ │ │ └── hyper v0.14.27 -│ │ │ │ ├── futures-core v0.3.28 -│ │ │ │ ├── futures-util v0.3.28 (*) -│ │ │ │ ├── bytes feature "default" (*) -│ │ │ │ ├── itoa feature "default" (*) -│ │ │ │ ├── tokio feature "default" (*) -│ │ │ │ ├── tokio feature "sync" -│ │ │ │ │ └── tokio v1.29.1 (*) -│ │ │ │ ├── pin-project-lite feature "default" (*) -│ │ │ │ ├── socket2 feature "all" (*) -│ │ │ │ ├── socket2 feature "default" (*) -│ │ │ │ ├── futures-channel feature "default" -│ │ │ │ │ ├── futures-channel v0.3.28 (*) -│ │ │ │ │ └── futures-channel feature "std" (*) -│ │ │ │ ├── http feature "default" (*) -│ │ │ │ ├── http-body feature "default" (*) -│ │ │ │ ├── tower-service feature "default" (*) -│ │ │ │ ├── h2 feature "default" -│ │ │ │ │ └── h2 v0.3.20 -│ │ │ │ │ ├── futures-core v0.3.28 -│ │ │ │ │ ├── futures-sink v0.3.28 -│ │ │ │ │ ├── futures-util v0.3.28 (*) -│ │ │ │ │ ├── bytes feature "default" (*) -│ │ │ │ │ ├── tokio feature "default" (*) -│ │ │ │ │ ├── tokio feature "io-util" -│ │ │ │ │ │ ├── tokio v1.29.1 (*) -│ │ │ │ │ │ └── tokio feature "bytes" -│ │ │ │ │ │ └── tokio v1.29.1 (*) -│ │ │ │ │ ├── slab feature "default" (*) -│ │ │ │ │ ├── http feature "default" (*) -│ │ │ │ │ ├── fnv feature "default" (*) -│ │ │ │ │ ├── indexmap feature "default" -│ │ │ │ │ │ └── indexmap v1.9.3 -│ │ │ │ │ │ └── hashbrown feature "raw" -│ │ │ │ │ │ └── hashbrown v0.12.3 (*) -│ │ │ │ │ │ [build-dependencies] -│ │ │ │ │ │ └── autocfg feature "default" (*) -│ │ │ │ │ ├── indexmap feature "std" -│ │ │ │ │ │ └── indexmap v1.9.3 (*) -│ │ │ │ │ ├── tokio-util feature "codec" -│ │ │ │ │ │ ├── tokio-util v0.7.8 -│ │ │ │ │ │ │ ├── bytes feature "default" (*) -│ │ │ │ │ │ │ ├── tokio feature "default" (*) -│ │ │ │ │ │ │ ├── tokio feature "sync" (*) -│ │ │ │ │ │ │ ├── pin-project-lite feature "default" (*) -│ │ │ │ │ │ │ ├── futures-core feature "default" -│ │ │ │ │ │ │ │ ├── futures-core v0.3.28 -│ │ │ │ │ │ │ │ └── futures-core feature "std" (*) -│ │ │ │ │ │ │ ├── futures-sink feature "default" -│ │ │ │ │ │ │ │ ├── futures-sink v0.3.28 -│ │ │ │ │ │ │ │ └── futures-sink feature "std" -│ │ │ │ │ │ │ │ ├── futures-sink v0.3.28 -│ │ │ │ │ │ │ │ └── futures-sink feature "alloc" -│ │ │ │ │ │ │ │ └── futures-sink v0.3.28 -│ │ │ │ │ │ │ └── tracing feature "std" -│ │ │ │ │ │ │ ├── tracing v0.1.37 -│ │ │ │ │ │ │ │ ├── tracing-core v0.1.31 -│ │ │ │ │ │ │ │ │ └── once_cell feature "default" (*) -│ │ │ │ │ │ │ │ ├── cfg-if feature "default" (*) -│ │ │ │ │ │ │ │ ├── log feature "default" (*) -│ │ │ │ │ │ │ │ ├── pin-project-lite feature "default" (*) -│ │ │ │ │ │ │ │ └── tracing-attributes feature "default" -│ │ │ │ │ │ │ │ └── tracing-attributes v0.1.26 (proc-macro) -│ │ │ │ │ │ │ │ ├── proc-macro2 feature "default" (*) -│ │ │ │ │ │ │ │ ├── quote feature "default" (*) -│ │ │ │ │ │ │ │ ├── syn feature "clone-impls" (*) -│ │ │ │ │ │ │ │ ├── syn feature "extra-traits" (*) -│ │ │ │ │ │ │ │ ├── syn feature "full" (*) -│ │ │ │ │ │ │ │ ├── syn feature "parsing" (*) -│ │ │ │ │ │ │ │ ├── syn feature "printing" (*) -│ │ │ │ │ │ │ │ ├── syn feature "proc-macro" (*) -│ │ │ │ │ │ │ │ └── syn feature "visit-mut" (*) -│ │ │ │ │ │ │ └── tracing-core feature "std" -│ │ │ │ │ │ │ ├── tracing-core v0.1.31 (*) -│ │ │ │ │ │ │ └── tracing-core feature "once_cell" -│ │ │ │ │ │ │ └── tracing-core v0.1.31 (*) -│ │ │ │ │ │ └── tokio-util feature "tracing" -│ │ │ │ │ │ └── tokio-util v0.7.8 (*) -│ │ │ │ │ ├── tokio-util feature "default" -│ │ │ │ │ │ └── tokio-util v0.7.8 (*) -│ │ │ │ │ └── tracing feature "std" (*) -│ │ │ │ ├── tracing feature "std" (*) -│ │ │ │ ├── httparse feature "default" -│ │ │ │ │ ├── httparse v1.8.0 -│ │ │ │ │ └── httparse feature "std" -│ │ │ │ │ └── httparse v1.8.0 -│ │ │ │ ├── httpdate feature "default" -│ │ │ │ │ └── httpdate v1.0.2 -│ │ │ │ └── want feature "default" -│ │ │ │ └── want v0.3.1 -│ │ │ │ └── try-lock feature "default" -│ │ │ │ └── try-lock v0.2.4 -│ │ │ ├── hyper feature "stream" -│ │ │ │ └── hyper v0.14.27 (*) -│ │ │ ├── matchit feature "default" -│ │ │ │ └── matchit v0.7.0 -│ │ │ ├── percent-encoding feature "default" -│ │ │ │ ├── percent-encoding v2.3.0 -│ │ │ │ └── percent-encoding feature "std" -│ │ │ │ ├── percent-encoding v2.3.0 -│ │ │ │ └── percent-encoding feature "alloc" -│ │ │ │ └── percent-encoding v2.3.0 -│ │ │ ├── sync_wrapper feature "default" -│ │ │ │ └── sync_wrapper v0.1.2 -│ │ │ └── tower feature "util" -│ │ │ ├── tower v0.4.13 -│ │ │ │ ├── tokio-util v0.7.8 (*) -│ │ │ │ ├── tokio feature "default" (*) -│ │ │ │ ├── tokio feature "sync" (*) -│ │ │ │ ├── pin-project-lite feature "default" (*) -│ │ │ │ ├── futures-core feature "default" (*) -│ │ │ │ ├── futures-util feature "alloc" (*) -│ │ │ │ ├── slab feature "default" (*) -│ │ │ │ ├── tower-layer feature "default" (*) -│ │ │ │ ├── tower-service feature "default" (*) -│ │ │ │ ├── indexmap feature "default" (*) -│ │ │ │ ├── tracing feature "std" (*) -│ │ │ │ ├── pin-project feature "default" -│ │ │ │ │ └── pin-project v1.1.2 -│ │ │ │ │ └── pin-project-internal feature "default" -│ │ │ │ │ └── pin-project-internal v1.1.2 (proc-macro) -│ │ │ │ │ ├── proc-macro2 feature "default" (*) -│ │ │ │ │ ├── quote feature "default" (*) -│ │ │ │ │ ├── syn feature "default" (*) -│ │ │ │ │ ├── syn feature "full" (*) -│ │ │ │ │ └── syn feature "visit-mut" (*) -│ │ │ │ ├── rand feature "default" -│ │ │ │ │ ├── rand v0.8.5 -│ │ │ │ │ │ ├── libc v0.2.147 -│ │ │ │ │ │ ├── rand_chacha v0.3.1 -│ │ │ │ │ │ │ ├── ppv-lite86 feature "simd" -│ │ │ │ │ │ │ │ └── ppv-lite86 v0.2.17 -│ │ │ │ │ │ │ └── rand_core feature "default" -│ │ │ │ │ │ │ └── rand_core v0.6.4 -│ │ │ │ │ │ │ └── getrandom feature "default" (*) -│ │ │ │ │ │ └── rand_core feature "default" (*) -│ │ │ │ │ ├── rand feature "std" -│ │ │ │ │ │ ├── rand v0.8.5 (*) -│ │ │ │ │ │ ├── rand feature "alloc" -│ │ │ │ │ │ │ ├── rand v0.8.5 (*) -│ │ │ │ │ │ │ └── rand_core feature "alloc" -│ │ │ │ │ │ │ └── rand_core v0.6.4 (*) -│ │ │ │ │ │ ├── rand feature "getrandom" -│ │ │ │ │ │ │ ├── rand v0.8.5 (*) -│ │ │ │ │ │ │ └── rand_core feature "getrandom" -│ │ │ │ │ │ │ └── rand_core v0.6.4 (*) -│ │ │ │ │ │ ├── rand feature "libc" -│ │ │ │ │ │ │ └── rand v0.8.5 (*) -│ │ │ │ │ │ ├── rand feature "rand_chacha" -│ │ │ │ │ │ │ └── rand v0.8.5 (*) -│ │ │ │ │ │ ├── rand_chacha feature "std" -│ │ │ │ │ │ │ ├── rand_chacha v0.3.1 (*) -│ │ │ │ │ │ │ └── ppv-lite86 feature "std" -│ │ │ │ │ │ │ └── ppv-lite86 v0.2.17 -│ │ │ │ │ │ └── rand_core feature "std" -│ │ │ │ │ │ ├── rand_core v0.6.4 (*) -│ │ │ │ │ │ ├── getrandom feature "std" -│ │ │ │ │ │ │ └── getrandom v0.2.10 (*) -│ │ │ │ │ │ ├── rand_core feature "alloc" (*) -│ │ │ │ │ │ └── rand_core feature "getrandom" (*) -│ │ │ │ │ └── rand feature "std_rng" -│ │ │ │ │ ├── rand v0.8.5 (*) -│ │ │ │ │ └── rand feature "rand_chacha" (*) -│ │ │ │ └── rand feature "small_rng" -│ │ │ │ └── rand v0.8.5 (*) -│ │ │ ├── tower feature "__common" -│ │ │ │ ├── tower v0.4.13 (*) -│ │ │ │ ├── tower feature "futures-core" -│ │ │ │ │ └── tower v0.4.13 (*) -│ │ │ │ └── tower feature "pin-project-lite" -│ │ │ │ └── tower v0.4.13 (*) -│ │ │ ├── tower feature "futures-util" -│ │ │ │ └── tower v0.4.13 (*) -│ │ │ └── tower feature "pin-project" -│ │ │ └── tower v0.4.13 (*) -│ │ │ [build-dependencies] -│ │ │ └── rustversion feature "default" (*) -│ │ ├── bytes feature "default" (*) -│ │ ├── async-trait feature "default" (*) -│ │ ├── prost feature "std" (*) -│ │ ├── tokio feature "default" (*) -│ │ ├── async-stream feature "default" -│ │ │ └── async-stream v0.3.5 -│ │ │ ├── pin-project-lite feature "default" (*) -│ │ │ ├── async-stream-impl feature "default" -│ │ │ │ └── async-stream-impl v0.3.5 (proc-macro) -│ │ │ │ ├── proc-macro2 feature "default" (*) -│ │ │ │ ├── quote feature "default" (*) -│ │ │ │ ├── syn feature "default" (*) -│ │ │ │ ├── syn feature "full" (*) -│ │ │ │ └── syn feature "visit-mut" (*) -│ │ │ └── futures-core feature "default" (*) -│ │ ├── http feature "default" (*) -│ │ ├── http-body feature "default" (*) -│ │ ├── tower-layer feature "default" (*) -│ │ ├── tower-service feature "default" (*) -│ │ ├── hyper feature "default" (*) -│ │ ├── hyper feature "full" -│ │ │ ├── hyper v0.14.27 (*) -│ │ │ ├── hyper feature "client" -│ │ │ │ └── hyper v0.14.27 (*) -│ │ │ ├── hyper feature "http1" -│ │ │ │ └── hyper v0.14.27 (*) -│ │ │ ├── hyper feature "http2" -│ │ │ │ ├── hyper v0.14.27 (*) -│ │ │ │ └── hyper feature "h2" -│ │ │ │ └── hyper v0.14.27 (*) -│ │ │ ├── hyper feature "runtime" -│ │ │ │ ├── hyper v0.14.27 (*) -│ │ │ │ ├── tokio feature "rt" (*) -│ │ │ │ ├── tokio feature "time" -│ │ │ │ │ └── tokio v1.29.1 (*) -│ │ │ │ └── hyper feature "tcp" -│ │ │ │ ├── hyper v0.14.27 (*) -│ │ │ │ ├── tokio feature "net" -│ │ │ │ │ ├── tokio v1.29.1 (*) -│ │ │ │ │ ├── tokio feature "libc" -│ │ │ │ │ │ └── tokio v1.29.1 (*) -│ │ │ │ │ ├── tokio feature "mio" -│ │ │ │ │ │ └── tokio v1.29.1 (*) -│ │ │ │ │ ├── tokio feature "socket2" -│ │ │ │ │ │ └── tokio v1.29.1 (*) -│ │ │ │ │ ├── mio feature "net" -│ │ │ │ │ │ └── mio v0.8.8 (*) -│ │ │ │ │ ├── mio feature "os-ext" -│ │ │ │ │ │ ├── mio v0.8.8 (*) -│ │ │ │ │ │ └── mio feature "os-poll" -│ │ │ │ │ │ └── mio v0.8.8 (*) -│ │ │ │ │ └── mio feature "os-poll" (*) -│ │ │ │ ├── tokio feature "rt" (*) -│ │ │ │ ├── tokio feature "time" (*) -│ │ │ │ └── hyper feature "socket2" -│ │ │ │ └── hyper v0.14.27 (*) -│ │ │ ├── hyper feature "server" -│ │ │ │ └── hyper v0.14.27 (*) -│ │ │ └── hyper feature "stream" (*) -│ │ ├── h2 feature "default" (*) -│ │ ├── tracing feature "default" -│ │ │ ├── tracing v0.1.37 (*) -│ │ │ ├── tracing feature "attributes" -│ │ │ │ ├── tracing v0.1.37 (*) -│ │ │ │ └── tracing feature "tracing-attributes" -│ │ │ │ └── tracing v0.1.37 (*) -│ │ │ └── tracing feature "std" (*) -│ │ ├── percent-encoding feature "default" (*) -│ │ ├── tower feature "balance" -│ │ │ ├── tower v0.4.13 (*) -│ │ │ ├── tower feature "discover" -│ │ │ │ ├── tower v0.4.13 (*) -│ │ │ │ └── tower feature "__common" (*) -│ │ │ ├── tower feature "load" -│ │ │ │ ├── tower v0.4.13 (*) -│ │ │ │ ├── tokio feature "time" (*) -│ │ │ │ ├── tower feature "__common" (*) -│ │ │ │ ├── tower feature "tokio" -│ │ │ │ │ └── tower v0.4.13 (*) -│ │ │ │ └── tower feature "tracing" -│ │ │ │ └── tower v0.4.13 (*) -│ │ │ ├── tower feature "make" -│ │ │ │ ├── tower v0.4.13 (*) -│ │ │ │ ├── tokio feature "io-std" -│ │ │ │ │ └── tokio v1.29.1 (*) -│ │ │ │ ├── tower feature "futures-util" (*) -│ │ │ │ ├── tower feature "pin-project-lite" (*) -│ │ │ │ └── tower feature "tokio" (*) -│ │ │ ├── tower feature "rand" -│ │ │ │ └── tower v0.4.13 (*) -│ │ │ ├── tower feature "ready-cache" -│ │ │ │ ├── tower v0.4.13 (*) -│ │ │ │ ├── tokio feature "sync" (*) -│ │ │ │ ├── tower feature "futures-core" (*) -│ │ │ │ ├── tower feature "futures-util" (*) -│ │ │ │ ├── tower feature "indexmap" -│ │ │ │ │ └── tower v0.4.13 (*) -│ │ │ │ ├── tower feature "pin-project-lite" (*) -│ │ │ │ ├── tower feature "tokio" (*) -│ │ │ │ └── tower feature "tracing" (*) -│ │ │ └── tower feature "slab" -│ │ │ └── tower v0.4.13 (*) -│ │ ├── tower feature "buffer" -│ │ │ ├── tower v0.4.13 (*) -│ │ │ ├── tokio feature "rt" (*) -│ │ │ ├── tokio feature "sync" (*) -│ │ │ ├── tower feature "__common" (*) -│ │ │ ├── tower feature "tokio" (*) -│ │ │ ├── tower feature "tokio-util" -│ │ │ │ └── tower v0.4.13 (*) -│ │ │ └── tower feature "tracing" (*) -│ │ ├── tower feature "discover" (*) -│ │ ├── tower feature "limit" -│ │ │ ├── tower v0.4.13 (*) -│ │ │ ├── tokio feature "sync" (*) -│ │ │ ├── tokio feature "time" (*) -│ │ │ ├── tower feature "__common" (*) -│ │ │ ├── tower feature "tokio" (*) -│ │ │ ├── tower feature "tokio-util" (*) -│ │ │ └── tower feature "tracing" (*) -│ │ ├── tower feature "load" (*) -│ │ ├── tower feature "make" (*) -│ │ ├── tower feature "timeout" -│ │ │ ├── tower v0.4.13 (*) -│ │ │ ├── tokio feature "time" (*) -│ │ │ ├── tower feature "pin-project-lite" (*) -│ │ │ └── tower feature "tokio" (*) -│ │ ├── tower feature "util" (*) -│ │ ├── pin-project feature "default" (*) -│ │ ├── base64 feature "default" -│ │ │ ├── base64 v0.21.2 -│ │ │ └── base64 feature "std" -│ │ │ └── base64 v0.21.2 -│ │ ├── hyper-timeout feature "default" -│ │ │ └── hyper-timeout v0.4.1 -│ │ │ ├── tokio feature "default" (*) -│ │ │ ├── pin-project-lite feature "default" (*) -│ │ │ ├── hyper feature "client" (*) -│ │ │ ├── hyper feature "default" (*) -│ │ │ └── tokio-io-timeout feature "default" -│ │ │ └── tokio-io-timeout v1.2.0 -│ │ │ ├── tokio feature "default" (*) -│ │ │ ├── tokio feature "time" (*) -│ │ │ └── pin-project-lite feature "default" (*) -│ │ └── tokio-stream feature "default" -│ │ ├── tokio-stream v0.1.14 -│ │ │ ├── tokio feature "default" (*) -│ │ │ ├── tokio feature "sync" (*) -│ │ │ ├── pin-project-lite feature "default" (*) -│ │ │ └── futures-core feature "default" (*) -│ │ └── tokio-stream feature "time" -│ │ ├── tokio-stream v0.1.14 (*) -│ │ └── tokio feature "time" (*) -│ ├── tonic feature "codegen" -│ │ └── tonic v0.10.0 (*) -│ ├── tonic feature "prost" -│ │ └── tonic v0.10.0 (*) -│ └── tonic feature "transport" -│ ├── tonic v0.10.0 (*) -│ ├── tokio feature "net" (*) -│ ├── tokio feature "time" (*) -│ └── tonic feature "channel" -│ └── tonic v0.10.0 (*) -│ [build-dependencies] -│ └── tonic-build feature "default" -│ ├── tonic-build v0.10.0 -│ │ ├── proc-macro2 feature "default" (*) -│ │ ├── quote feature "default" (*) -│ │ ├── syn feature "default" (*) -│ │ ├── prettyplease feature "default" -│ │ │ └── prettyplease v0.2.12 -│ │ │ ├── proc-macro2 v1.0.66 (*) -│ │ │ └── syn feature "full" (*) -│ │ └── prost-build feature "default" -│ │ ├── prost-build v0.12.1 -│ │ │ ├── bytes v1.4.0 -│ │ │ ├── multimap v0.8.3 -│ │ │ ├── petgraph v0.6.3 -│ │ │ │ ├── fixedbitset v0.4.2 -│ │ │ │ ├── indexmap feature "default" (*) -│ │ │ │ └── indexmap feature "std" (*) -│ │ │ ├── prost v0.12.1 -│ │ │ │ ├── bytes v1.4.0 -│ │ │ │ └── prost-derive feature "default" (*) -│ │ │ ├── prost-types v0.12.1 -│ │ │ │ └── prost feature "prost-derive" -│ │ │ │ └── prost v0.12.1 (*) -│ │ │ ├── syn feature "default" (*) -│ │ │ ├── syn feature "full" (*) -│ │ │ ├── once_cell feature "default" (*) -│ │ │ ├── itertools feature "use_alloc" (*) -│ │ │ ├── prettyplease feature "default" (*) -│ │ │ ├── heck feature "default" -│ │ │ │ └── heck v0.4.1 -│ │ │ ├── log feature "default" -│ │ │ │ └── log v0.4.19 -│ │ │ ├── regex feature "std" -│ │ │ │ ├── regex v1.9.3 -│ │ │ │ │ ├── regex-syntax v0.7.4 -│ │ │ │ │ ├── regex-automata feature "alloc" -│ │ │ │ │ │ └── regex-automata v0.3.6 -│ │ │ │ │ │ └── regex-syntax v0.7.4 -│ │ │ │ │ ├── regex-automata feature "meta" -│ │ │ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ │ │ ├── regex-automata feature "nfa-pikevm" -│ │ │ │ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ │ │ │ └── regex-automata feature "nfa-thompson" -│ │ │ │ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ │ │ │ └── regex-automata feature "alloc" (*) -│ │ │ │ │ │ └── regex-automata feature "syntax" -│ │ │ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ │ │ └── regex-automata feature "alloc" (*) -│ │ │ │ │ ├── regex-automata feature "nfa-pikevm" (*) -│ │ │ │ │ └── regex-automata feature "syntax" (*) -│ │ │ │ ├── regex-automata feature "std" -│ │ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ │ ├── regex-automata feature "alloc" (*) -│ │ │ │ │ └── regex-syntax feature "std" -│ │ │ │ │ └── regex-syntax v0.7.4 -│ │ │ │ └── regex-syntax feature "std" (*) -│ │ │ ├── regex feature "unicode-bool" -│ │ │ │ ├── regex v1.9.3 (*) -│ │ │ │ ├── regex-automata feature "unicode-bool" -│ │ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ │ └── regex-syntax feature "unicode-bool" -│ │ │ │ │ └── regex-syntax v0.7.4 -│ │ │ │ └── regex-syntax feature "unicode-bool" (*) -│ │ │ ├── tempfile feature "default" -│ │ │ │ └── tempfile v3.7.0 -│ │ │ │ ├── cfg-if feature "default" (*) -│ │ │ │ ├── fastrand feature "default" -│ │ │ │ │ ├── fastrand v2.0.0 -│ │ │ │ │ └── fastrand feature "std" -│ │ │ │ │ ├── fastrand v2.0.0 -│ │ │ │ │ └── fastrand feature "alloc" -│ │ │ │ │ └── fastrand v2.0.0 -│ │ │ │ ├── rustix feature "default" -│ │ │ │ │ ├── rustix v0.38.4 -│ │ │ │ │ │ ├── bitflags v2.3.3 -│ │ │ │ │ │ ├── linux-raw-sys feature "errno" -│ │ │ │ │ │ │ └── linux-raw-sys v0.4.3 -│ │ │ │ │ │ ├── linux-raw-sys feature "general" -│ │ │ │ │ │ │ └── linux-raw-sys v0.4.3 -│ │ │ │ │ │ ├── linux-raw-sys feature "ioctl" -│ │ │ │ │ │ │ └── linux-raw-sys v0.4.3 -│ │ │ │ │ │ └── linux-raw-sys feature "no_std" -│ │ │ │ │ │ └── linux-raw-sys v0.4.3 -│ │ │ │ │ ├── rustix feature "std" -│ │ │ │ │ │ ├── rustix v0.38.4 (*) -│ │ │ │ │ │ └── bitflags feature "std" -│ │ │ │ │ │ └── bitflags v2.3.3 -│ │ │ │ │ └── rustix feature "use-libc-auxv" -│ │ │ │ │ └── rustix v0.38.4 (*) -│ │ │ │ └── rustix feature "fs" -│ │ │ │ └── rustix v0.38.4 (*) -│ │ │ └── which feature "default" -│ │ │ └── which v4.4.0 -│ │ │ ├── either feature "default" -│ │ │ │ ├── either v1.9.0 -│ │ │ │ └── either feature "use_std" -│ │ │ │ └── either v1.9.0 -│ │ │ └── libc feature "default" -│ │ │ ├── libc v0.2.147 -│ │ │ └── libc feature "std" -│ │ │ └── libc v0.2.147 -│ │ └── prost-build feature "format" -│ │ ├── prost-build v0.12.1 (*) -│ │ ├── prost-build feature "prettyplease" -│ │ │ └── prost-build v0.12.1 (*) -│ │ └── prost-build feature "syn" -│ │ └── prost-build v0.12.1 (*) -│ ├── tonic-build feature "prost" -│ │ ├── tonic-build v0.10.0 (*) -│ │ └── tonic-build feature "prost-build" -│ │ └── tonic-build v0.10.0 (*) -│ └── tonic-build feature "transport" -│ └── tonic-build v0.10.0 (*) -├── prost feature "default" (*) -├── tokio feature "default" (*) -├── log feature "default" (*) -├── tonic feature "default" (*) -├── futures-core feature "default" (*) -├── futures-util feature "default" -│ ├── futures-util v0.3.28 (*) -│ ├── futures-util feature "async-await" -│ │ └── futures-util v0.3.28 (*) -│ ├── futures-util feature "async-await-macro" -│ │ ├── futures-util v0.3.28 (*) -│ │ ├── futures-util feature "async-await" (*) -│ │ └── futures-util feature "futures-macro" -│ │ └── futures-util v0.3.28 (*) -│ └── futures-util feature "std" -│ ├── futures-util v0.3.28 (*) -│ ├── futures-core feature "std" (*) -│ ├── futures-util feature "alloc" (*) -│ ├── futures-util feature "slab" -│ │ └── futures-util v0.3.28 (*) -│ └── futures-task feature "std" -│ ├── futures-task v0.3.28 -│ └── futures-task feature "alloc" (*) -├── http feature "default" (*) -├── http-body feature "default" (*) -├── hyper feature "default" (*) -├── tower feature "default" -│ ├── tower v0.4.13 (*) -│ └── tower feature "log" -│ ├── tower v0.4.13 (*) -│ ├── tracing feature "log" -│ │ └── tracing v0.1.37 (*) -│ └── tower feature "tracing" (*) -├── dyn-clone feature "default" -│ └── dyn-clone v1.0.14 -├── futures feature "default" -│ ├── futures v0.3.28 -│ │ ├── futures-core v0.3.28 -│ │ ├── futures-executor v0.3.28 -│ │ │ ├── futures-core v0.3.28 -│ │ │ ├── futures-task v0.3.28 -│ │ │ └── futures-util v0.3.28 (*) -│ │ ├── futures-io v0.3.28 -│ │ ├── futures-sink v0.3.28 -│ │ ├── futures-task v0.3.28 -│ │ ├── futures-util feature "sink" -│ │ │ ├── futures-util v0.3.28 (*) -│ │ │ └── futures-util feature "futures-sink" -│ │ │ └── futures-util v0.3.28 (*) -│ │ └── futures-channel feature "sink" -│ │ ├── futures-channel v0.3.28 (*) -│ │ └── futures-channel feature "futures-sink" -│ │ └── futures-channel v0.3.28 (*) -│ ├── futures feature "async-await" -│ │ ├── futures v0.3.28 (*) -│ │ ├── futures-util feature "async-await" (*) -│ │ └── futures-util feature "async-await-macro" (*) -│ ├── futures feature "executor" -│ │ ├── futures v0.3.28 (*) -│ │ ├── futures feature "futures-executor" -│ │ │ └── futures v0.3.28 (*) -│ │ ├── futures feature "std" -│ │ │ ├── futures v0.3.28 (*) -│ │ │ ├── futures-core feature "std" (*) -│ │ │ ├── futures-util feature "channel" -│ │ │ │ ├── futures-util v0.3.28 (*) -│ │ │ │ ├── futures-util feature "futures-channel" -│ │ │ │ │ └── futures-util v0.3.28 (*) -│ │ │ │ └── futures-util feature "std" (*) -│ │ │ ├── futures-util feature "io" -│ │ │ │ ├── futures-util v0.3.28 (*) -│ │ │ │ ├── futures-util feature "futures-io" -│ │ │ │ │ └── futures-util v0.3.28 (*) -│ │ │ │ ├── futures-util feature "memchr" -│ │ │ │ │ └── futures-util v0.3.28 (*) -│ │ │ │ └── futures-util feature "std" (*) -│ │ │ ├── futures-util feature "std" (*) -│ │ │ ├── futures-sink feature "std" (*) -│ │ │ ├── futures-io feature "std" (*) -│ │ │ ├── futures-task feature "std" (*) -│ │ │ └── futures feature "alloc" -│ │ │ ├── futures v0.3.28 (*) -│ │ │ ├── futures-core feature "alloc" (*) -│ │ │ ├── futures-util feature "alloc" (*) -│ │ │ ├── futures-channel feature "alloc" (*) -│ │ │ ├── futures-sink feature "alloc" (*) -│ │ │ └── futures-task feature "alloc" (*) -│ │ └── futures-executor feature "std" -│ │ ├── futures-executor v0.3.28 (*) -│ │ ├── futures-core feature "std" (*) -│ │ ├── futures-util feature "std" (*) -│ │ └── futures-task feature "std" (*) -│ └── futures feature "std" (*) -├── parking_lot feature "default" -│ └── parking_lot v0.12.1 -│ ├── lock_api feature "default" -│ │ ├── lock_api v0.4.10 -│ │ │ └── scopeguard v1.2.0 -│ │ │ [build-dependencies] -│ │ │ └── autocfg feature "default" (*) -│ │ └── lock_api feature "atomic_usize" -│ │ └── lock_api v0.4.10 (*) -│ └── parking_lot_core feature "default" -│ └── parking_lot_core v0.9.8 -│ ├── cfg-if feature "default" (*) -│ ├── libc feature "default" (*) -│ └── smallvec feature "default" -│ └── smallvec v1.11.0 -├── regex feature "default" -│ ├── regex v1.9.3 -│ │ ├── regex-syntax v0.7.4 -│ │ ├── memchr feature "default" (*) -│ │ ├── aho-corasick feature "default" -│ │ │ ├── aho-corasick v1.0.2 -│ │ │ │ └── memchr v2.5.0 -│ │ │ ├── aho-corasick feature "perf-literal" -│ │ │ │ └── aho-corasick v1.0.2 (*) -│ │ │ └── aho-corasick feature "std" -│ │ │ ├── aho-corasick v1.0.2 (*) -│ │ │ └── memchr feature "std" (*) -│ │ ├── regex-automata feature "alloc" -│ │ │ └── regex-automata v0.3.6 -│ │ │ ├── aho-corasick v1.0.2 (*) -│ │ │ ├── memchr v2.5.0 -│ │ │ └── regex-syntax v0.7.4 -│ │ ├── regex-automata feature "meta" -│ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ ├── regex-automata feature "nfa-pikevm" -│ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ └── regex-automata feature "nfa-thompson" -│ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ └── regex-automata feature "alloc" (*) -│ │ │ └── regex-automata feature "syntax" -│ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ └── regex-automata feature "alloc" (*) -│ │ ├── regex-automata feature "nfa-pikevm" (*) -│ │ └── regex-automata feature "syntax" (*) -│ ├── regex feature "perf" -│ │ ├── regex v1.9.3 (*) -│ │ ├── regex feature "perf-backtrack" -│ │ │ ├── regex v1.9.3 (*) -│ │ │ └── regex-automata feature "nfa-backtrack" -│ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ └── regex-automata feature "nfa-thompson" (*) -│ │ ├── regex feature "perf-cache" -│ │ │ └── regex v1.9.3 (*) -│ │ ├── regex feature "perf-dfa" -│ │ │ ├── regex v1.9.3 (*) -│ │ │ └── regex-automata feature "hybrid" -│ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ ├── regex-automata feature "alloc" (*) -│ │ │ └── regex-automata feature "nfa-thompson" (*) -│ │ ├── regex feature "perf-inline" -│ │ │ ├── regex v1.9.3 (*) -│ │ │ └── regex-automata feature "perf-inline" -│ │ │ └── regex-automata v0.3.6 (*) -│ │ ├── regex feature "perf-literal" -│ │ │ ├── regex v1.9.3 (*) -│ │ │ └── regex-automata feature "perf-literal" -│ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ ├── regex-automata feature "perf-literal-multisubstring" -│ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ └── regex-automata feature "std" -│ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ ├── memchr feature "std" (*) -│ │ │ │ ├── aho-corasick feature "std" (*) -│ │ │ │ ├── regex-automata feature "alloc" (*) -│ │ │ │ └── regex-syntax feature "std" -│ │ │ │ └── regex-syntax v0.7.4 -│ │ │ └── regex-automata feature "perf-literal-substring" -│ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ └── aho-corasick feature "perf-literal" (*) -│ │ └── regex feature "perf-onepass" -│ │ ├── regex v1.9.3 (*) -│ │ └── regex-automata feature "dfa-onepass" -│ │ ├── regex-automata v0.3.6 (*) -│ │ └── regex-automata feature "nfa-thompson" (*) -│ ├── regex feature "std" -│ │ ├── regex v1.9.3 (*) -│ │ ├── memchr feature "std" (*) -│ │ ├── aho-corasick feature "std" (*) -│ │ ├── regex-automata feature "std" (*) -│ │ └── regex-syntax feature "std" (*) -│ ├── regex feature "unicode" -│ │ ├── regex v1.9.3 (*) -│ │ ├── regex feature "unicode-age" -│ │ │ ├── regex v1.9.3 (*) -│ │ │ ├── regex-automata feature "unicode-age" -│ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ └── regex-syntax feature "unicode-age" -│ │ │ │ └── regex-syntax v0.7.4 -│ │ │ └── regex-syntax feature "unicode-age" (*) -│ │ ├── regex feature "unicode-bool" -│ │ │ ├── regex v1.9.3 (*) -│ │ │ ├── regex-automata feature "unicode-bool" -│ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ └── regex-syntax feature "unicode-bool" -│ │ │ │ └── regex-syntax v0.7.4 -│ │ │ └── regex-syntax feature "unicode-bool" (*) -│ │ ├── regex feature "unicode-case" -│ │ │ ├── regex v1.9.3 (*) -│ │ │ ├── regex-automata feature "unicode-case" -│ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ └── regex-syntax feature "unicode-case" -│ │ │ │ └── regex-syntax v0.7.4 -│ │ │ └── regex-syntax feature "unicode-case" (*) -│ │ ├── regex feature "unicode-gencat" -│ │ │ ├── regex v1.9.3 (*) -│ │ │ ├── regex-automata feature "unicode-gencat" -│ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ └── regex-syntax feature "unicode-gencat" -│ │ │ │ └── regex-syntax v0.7.4 -│ │ │ └── regex-syntax feature "unicode-gencat" (*) -│ │ ├── regex feature "unicode-perl" -│ │ │ ├── regex v1.9.3 (*) -│ │ │ ├── regex-automata feature "unicode-perl" -│ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ └── regex-syntax feature "unicode-perl" -│ │ │ │ └── regex-syntax v0.7.4 -│ │ │ ├── regex-automata feature "unicode-word-boundary" -│ │ │ │ └── regex-automata v0.3.6 (*) -│ │ │ └── regex-syntax feature "unicode-perl" (*) -│ │ ├── regex feature "unicode-script" -│ │ │ ├── regex v1.9.3 (*) -│ │ │ ├── regex-automata feature "unicode-script" -│ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ └── regex-syntax feature "unicode-script" -│ │ │ │ └── regex-syntax v0.7.4 -│ │ │ └── regex-syntax feature "unicode-script" (*) -│ │ ├── regex feature "unicode-segment" -│ │ │ ├── regex v1.9.3 (*) -│ │ │ ├── regex-automata feature "unicode-segment" -│ │ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ │ └── regex-syntax feature "unicode-segment" -│ │ │ │ └── regex-syntax v0.7.4 -│ │ │ └── regex-syntax feature "unicode-segment" (*) -│ │ ├── regex-automata feature "unicode" -│ │ │ ├── regex-automata v0.3.6 (*) -│ │ │ ├── regex-automata feature "unicode-age" (*) -│ │ │ ├── regex-automata feature "unicode-bool" (*) -│ │ │ ├── regex-automata feature "unicode-case" (*) -│ │ │ ├── regex-automata feature "unicode-gencat" (*) -│ │ │ ├── regex-automata feature "unicode-perl" (*) -│ │ │ ├── regex-automata feature "unicode-script" (*) -│ │ │ ├── regex-automata feature "unicode-segment" (*) -│ │ │ ├── regex-automata feature "unicode-word-boundary" (*) -│ │ │ └── regex-syntax feature "unicode" -│ │ │ ├── regex-syntax v0.7.4 -│ │ │ ├── regex-syntax feature "unicode-age" (*) -│ │ │ ├── regex-syntax feature "unicode-bool" (*) -│ │ │ ├── regex-syntax feature "unicode-case" (*) -│ │ │ ├── regex-syntax feature "unicode-gencat" (*) -│ │ │ ├── regex-syntax feature "unicode-perl" (*) -│ │ │ ├── regex-syntax feature "unicode-script" (*) -│ │ │ └── regex-syntax feature "unicode-segment" (*) -│ │ └── regex-syntax feature "unicode" (*) -│ └── regex-syntax feature "default" -│ ├── regex-syntax v0.7.4 -│ ├── regex-syntax feature "std" (*) -│ └── regex-syntax feature "unicode" (*) -└── url feature "default" - └── url v2.4.0 - ├── percent-encoding feature "default" (*) - ├── form_urlencoded feature "default" - │ ├── form_urlencoded v1.2.0 - │ │ └── percent-encoding v2.3.0 - │ └── form_urlencoded feature "std" - │ ├── form_urlencoded v1.2.0 (*) - │ ├── percent-encoding feature "std" (*) - │ └── form_urlencoded feature "alloc" - │ ├── form_urlencoded v1.2.0 (*) - │ └── percent-encoding feature "alloc" (*) - └── idna feature "default" - ├── idna v0.4.0 - │ ├── unicode-normalization v0.1.22 - │ │ ├── tinyvec feature "alloc" - │ │ │ ├── tinyvec v1.6.0 - │ │ │ │ └── tinyvec_macros feature "default" - │ │ │ │ └── tinyvec_macros v0.1.1 - │ │ │ └── tinyvec feature "tinyvec_macros" - │ │ │ └── tinyvec v1.6.0 (*) - │ │ └── tinyvec feature "default" - │ │ └── tinyvec v1.6.0 (*) - │ └── unicode-bidi feature "hardcoded-data" - │ └── unicode-bidi v0.3.13 - └── idna feature "std" - ├── idna v0.4.0 (*) - ├── idna feature "alloc" - │ └── idna v0.4.0 (*) - ├── unicode-bidi feature "std" - │ └── unicode-bidi v0.3.13 - └── unicode-normalization feature "std" - └── unicode-normalization v0.1.22 (*) -[build-dependencies] -└── tonic-build feature "default" (*) - -core-protobuf-data-access v0.1.0 (/home/ashbeitz/repos/ibeji/core/protobuf_data_access) (*) - -digital-twin-model v0.1.0 (/home/ashbeitz/repos/ibeji/digital-twin-model) -├── serde feature "default" (*) -└── serde_derive feature "default" (*) - -dtdl-tools v0.1.0 (/home/ashbeitz/repos/ibeji/dtdl-tools) - -invehicle-digital-twin v0.1.0 (/home/ashbeitz/repos/ibeji/core/invehicle-digital-twin) -├── common feature "default" (command-line) -│ └── common v0.1.0 (/home/ashbeitz/repos/ibeji/core/common) (*) -├── bytes feature "default" (*) -├── config feature "default" (*) -├── serde feature "default" (*) -├── serde feature "derive" (*) -├── serde_derive feature "default" (*) -├── serde_json feature "default" (*) -├── yaml-rust feature "default" (*) -├── core-protobuf-data-access feature "default" (command-line) (*) -├── prost feature "default" (*) -├── tokio feature "default" (*) -├── tokio feature "macros" (*) -├── tokio feature "rt-multi-thread" (*) -├── log feature "default" (*) -├── tonic feature "default" (*) -├── http feature "default" (*) -├── tower feature "default" (*) -├── futures feature "default" (*) -├── parking_lot feature "default" (*) -├── url feature "default" (*) -├── async-std feature "attributes" -│ ├── async-std v1.12.0 -│ │ ├── futures-core v0.3.28 -│ │ ├── once_cell feature "default" (*) -│ │ ├── memchr feature "default" (*) -│ │ ├── log feature "default" (*) -│ │ ├── log feature "kv_unstable" -│ │ │ ├── log v0.4.19 (*) -│ │ │ └── log feature "value-bag" -│ │ │ └── log v0.4.19 (*) -│ │ ├── pin-project-lite feature "default" (*) -│ │ ├── futures-io feature "default" -│ │ │ ├── futures-io v0.3.28 -│ │ │ └── futures-io feature "std" (*) -│ │ ├── pin-utils feature "default" (*) -│ │ ├── slab feature "default" (*) -│ │ ├── async-attributes feature "default" -│ │ │ └── async-attributes v1.1.2 (proc-macro) -│ │ │ ├── quote feature "default" (*) -│ │ │ ├── syn feature "default" -│ │ │ │ ├── syn v1.0.109 -│ │ │ │ │ ├── proc-macro2 v1.0.66 (*) -│ │ │ │ │ ├── quote v1.0.32 (*) -│ │ │ │ │ └── unicode-ident feature "default" (*) -│ │ │ │ ├── syn feature "clone-impls" -│ │ │ │ │ └── syn v1.0.109 (*) -│ │ │ │ ├── syn feature "derive" -│ │ │ │ │ └── syn v1.0.109 (*) -│ │ │ │ ├── syn feature "parsing" -│ │ │ │ │ └── syn v1.0.109 (*) -│ │ │ │ ├── syn feature "printing" -│ │ │ │ │ ├── syn v1.0.109 (*) -│ │ │ │ │ └── syn feature "quote" -│ │ │ │ │ └── syn v1.0.109 (*) -│ │ │ │ └── syn feature "proc-macro" -│ │ │ │ ├── syn v1.0.109 (*) -│ │ │ │ ├── proc-macro2 feature "proc-macro" (*) -│ │ │ │ ├── quote feature "proc-macro" (*) -│ │ │ │ └── syn feature "quote" (*) -│ │ │ └── syn feature "full" -│ │ │ └── syn v1.0.109 (*) -│ │ ├── async-channel feature "default" -│ │ │ └── async-channel v1.9.0 -│ │ │ ├── futures-core feature "default" (*) -│ │ │ ├── concurrent-queue feature "default" -│ │ │ │ ├── concurrent-queue v2.2.0 -│ │ │ │ │ └── crossbeam-utils v0.8.16 -│ │ │ │ │ └── cfg-if feature "default" (*) -│ │ │ │ └── concurrent-queue feature "std" -│ │ │ │ └── concurrent-queue v2.2.0 (*) -│ │ │ └── event-listener feature "default" -│ │ │ └── event-listener v2.5.3 -│ │ ├── crossbeam-utils feature "default" -│ │ │ ├── crossbeam-utils v0.8.16 (*) -│ │ │ └── crossbeam-utils feature "std" -│ │ │ └── crossbeam-utils v0.8.16 (*) -│ │ ├── async-global-executor feature "async-io" -│ │ │ └── async-global-executor v2.3.1 -│ │ │ ├── once_cell feature "default" (*) -│ │ │ ├── async-channel feature "default" (*) -│ │ │ ├── async-executor feature "default" -│ │ │ │ └── async-executor v1.5.1 -│ │ │ │ ├── slab feature "default" (*) -│ │ │ │ ├── concurrent-queue feature "default" (*) -│ │ │ │ ├── async-lock feature "default" -│ │ │ │ │ └── async-lock v2.7.0 -│ │ │ │ │ └── event-listener feature "default" (*) -│ │ │ │ ├── async-task feature "default" -│ │ │ │ │ ├── async-task v4.4.0 -│ │ │ │ │ └── async-task feature "std" -│ │ │ │ │ └── async-task v4.4.0 -│ │ │ │ ├── fastrand feature "default" -│ │ │ │ │ └── fastrand v1.9.0 -│ │ │ │ └── futures-lite feature "default" -│ │ │ │ ├── futures-lite v1.13.0 -│ │ │ │ │ ├── futures-core v0.3.28 -│ │ │ │ │ ├── memchr feature "default" (*) -│ │ │ │ │ ├── pin-project-lite feature "default" (*) -│ │ │ │ │ ├── futures-io feature "default" (*) -│ │ │ │ │ ├── fastrand feature "default" (*) -│ │ │ │ │ ├── parking feature "default" -│ │ │ │ │ │ └── parking v2.1.0 -│ │ │ │ │ └── waker-fn feature "default" -│ │ │ │ │ └── waker-fn v1.1.0 -│ │ │ │ └── futures-lite feature "std" -│ │ │ │ ├── futures-lite v1.13.0 (*) -│ │ │ │ ├── futures-lite feature "alloc" -│ │ │ │ │ └── futures-lite v1.13.0 (*) -│ │ │ │ ├── futures-lite feature "fastrand" -│ │ │ │ │ └── futures-lite v1.13.0 (*) -│ │ │ │ ├── futures-lite feature "futures-io" -│ │ │ │ │ └── futures-lite v1.13.0 (*) -│ │ │ │ ├── futures-lite feature "memchr" -│ │ │ │ │ └── futures-lite v1.13.0 (*) -│ │ │ │ ├── futures-lite feature "parking" -│ │ │ │ │ └── futures-lite v1.13.0 (*) -│ │ │ │ └── futures-lite feature "waker-fn" -│ │ │ │ └── futures-lite v1.13.0 (*) -│ │ │ ├── async-lock feature "default" (*) -│ │ │ ├── futures-lite feature "default" (*) -│ │ │ ├── async-io feature "default" -│ │ │ │ └── async-io v1.13.0 -│ │ │ │ ├── cfg-if feature "default" (*) -│ │ │ │ ├── log feature "default" (*) -│ │ │ │ ├── socket2 feature "all" (*) -│ │ │ │ ├── socket2 feature "default" (*) -│ │ │ │ ├── slab feature "default" (*) -│ │ │ │ ├── concurrent-queue feature "default" (*) -│ │ │ │ ├── async-lock feature "default" (*) -│ │ │ │ ├── futures-lite feature "default" (*) -│ │ │ │ ├── parking feature "default" (*) -│ │ │ │ ├── waker-fn feature "default" (*) -│ │ │ │ ├── polling feature "default" -│ │ │ │ │ ├── polling v2.8.0 -│ │ │ │ │ │ ├── cfg-if feature "default" (*) -│ │ │ │ │ │ ├── libc feature "default" (*) -│ │ │ │ │ │ └── log feature "default" (*) -│ │ │ │ │ │ [build-dependencies] -│ │ │ │ │ │ └── autocfg feature "default" (*) -│ │ │ │ │ └── polling feature "std" -│ │ │ │ │ └── polling v2.8.0 (*) -│ │ │ │ ├── rustix feature "fs" -│ │ │ │ │ └── rustix v0.37.23 -│ │ │ │ │ ├── bitflags feature "default" (*) -│ │ │ │ │ ├── io-lifetimes feature "close" -│ │ │ │ │ │ ├── io-lifetimes v1.0.11 -│ │ │ │ │ │ │ └── libc feature "default" (*) -│ │ │ │ │ │ ├── io-lifetimes feature "hermit-abi" -│ │ │ │ │ │ │ └── io-lifetimes v1.0.11 (*) -│ │ │ │ │ │ ├── io-lifetimes feature "libc" -│ │ │ │ │ │ │ └── io-lifetimes v1.0.11 (*) -│ │ │ │ │ │ └── io-lifetimes feature "windows-sys" -│ │ │ │ │ │ └── io-lifetimes v1.0.11 (*) -│ │ │ │ │ ├── linux-raw-sys feature "errno" -│ │ │ │ │ │ └── linux-raw-sys v0.3.8 -│ │ │ │ │ ├── linux-raw-sys feature "general" -│ │ │ │ │ │ └── linux-raw-sys v0.3.8 -│ │ │ │ │ ├── linux-raw-sys feature "ioctl" -│ │ │ │ │ │ └── linux-raw-sys v0.3.8 -│ │ │ │ │ └── linux-raw-sys feature "no_std" -│ │ │ │ │ └── linux-raw-sys v0.3.8 -│ │ │ │ └── rustix feature "std" -│ │ │ │ ├── rustix v0.37.23 (*) -│ │ │ │ └── rustix feature "io-lifetimes" -│ │ │ │ └── rustix v0.37.23 (*) -│ │ │ │ [build-dependencies] -│ │ │ │ └── autocfg feature "default" (*) -│ │ │ └── blocking feature "default" -│ │ │ └── blocking v1.3.1 -│ │ │ ├── log feature "default" (*) -│ │ │ ├── async-channel feature "default" (*) -│ │ │ ├── async-lock feature "default" (*) -│ │ │ ├── async-task feature "default" (*) -│ │ │ ├── fastrand feature "default" (*) -│ │ │ ├── futures-lite feature "default" (*) -│ │ │ └── atomic-waker feature "default" -│ │ │ └── atomic-waker v1.1.1 -│ │ ├── async-global-executor feature "default" -│ │ │ ├── async-global-executor v2.3.1 (*) -│ │ │ └── async-global-executor feature "async-io" (*) -│ │ ├── async-lock feature "default" (*) -│ │ ├── futures-lite feature "default" (*) -│ │ ├── async-io feature "default" (*) -│ │ └── kv-log-macro feature "default" -│ │ └── kv-log-macro v1.0.7 -│ │ ├── log feature "default" (*) -│ │ └── log feature "kv_unstable" (*) -│ └── async-std feature "async-attributes" -│ └── async-std v1.12.0 (*) -├── async-std feature "default" -│ ├── async-std v1.12.0 (*) -│ ├── async-std feature "async-global-executor" -│ │ └── async-std v1.12.0 (*) -│ ├── async-std feature "async-io" -│ │ └── async-std v1.12.0 (*) -│ ├── async-std feature "futures-lite" -│ │ └── async-std v1.12.0 (*) -│ ├── async-std feature "gloo-timers" -│ │ └── async-std v1.12.0 (*) -│ ├── async-std feature "kv-log-macro" -│ │ └── async-std v1.12.0 (*) -│ ├── async-std feature "log" -│ │ └── async-std v1.12.0 (*) -│ ├── async-std feature "pin-project-lite" -│ │ └── async-std v1.12.0 (*) -│ └── async-std feature "std" -│ ├── async-std v1.12.0 (*) -│ ├── futures-core feature "std" (*) -│ ├── async-std feature "alloc" -│ │ ├── async-std v1.12.0 (*) -│ │ ├── futures-core feature "alloc" (*) -│ │ ├── async-std feature "futures-core" -│ │ │ └── async-std v1.12.0 (*) -│ │ └── async-std feature "pin-project-lite" (*) -│ ├── async-std feature "async-channel" -│ │ └── async-std v1.12.0 (*) -│ ├── async-std feature "async-lock" -│ │ └── async-std v1.12.0 (*) -│ ├── async-std feature "crossbeam-utils" -│ │ └── async-std v1.12.0 (*) -│ ├── async-std feature "futures-channel" -│ │ └── async-std v1.12.0 (*) -│ ├── async-std feature "futures-core" (*) -│ ├── async-std feature "futures-io" -│ │ └── async-std v1.12.0 (*) -│ ├── async-std feature "memchr" -│ │ └── async-std v1.12.0 (*) -│ ├── async-std feature "once_cell" -│ │ └── async-std v1.12.0 (*) -│ ├── async-std feature "pin-utils" -│ │ └── async-std v1.12.0 (*) -│ ├── async-std feature "slab" -│ │ └── async-std v1.12.0 (*) -│ └── async-std feature "wasm-bindgen-futures" -│ └── async-std v1.12.0 (*) -├── env_logger feature "default" -│ ├── env_logger v0.10.0 -│ │ ├── log feature "default" (*) -│ │ ├── log feature "std" -│ │ │ └── log v0.4.19 (*) -│ │ ├── regex feature "perf" (*) -│ │ ├── regex feature "std" (*) -│ │ ├── humantime feature "default" -│ │ │ └── humantime v2.1.0 -│ │ ├── is-terminal feature "default" -│ │ │ └── is-terminal v0.4.9 -│ │ │ ├── rustix feature "default" -│ │ │ │ ├── rustix v0.38.4 -│ │ │ │ │ ├── bitflags v2.3.3 -│ │ │ │ │ ├── linux-raw-sys feature "errno" (*) -│ │ │ │ │ ├── linux-raw-sys feature "general" (*) -│ │ │ │ │ ├── linux-raw-sys feature "ioctl" (*) -│ │ │ │ │ └── linux-raw-sys feature "no_std" (*) -│ │ │ │ ├── rustix feature "std" -│ │ │ │ │ ├── rustix v0.38.4 (*) -│ │ │ │ │ └── bitflags feature "std" (*) -│ │ │ │ └── rustix feature "use-libc-auxv" -│ │ │ │ └── rustix v0.38.4 (*) -│ │ │ └── rustix feature "termios" -│ │ │ └── rustix v0.38.4 (*) -│ │ └── termcolor feature "default" -│ │ └── termcolor v1.2.0 -│ ├── env_logger feature "auto-color" -│ │ ├── env_logger v0.10.0 (*) -│ │ └── env_logger feature "color" -│ │ └── env_logger v0.10.0 (*) -│ ├── env_logger feature "humantime" -│ │ └── env_logger v0.10.0 (*) -│ └── env_logger feature "regex" -│ └── env_logger v0.10.0 (*) -├── iref feature "default" -│ └── iref v2.2.3 -│ ├── smallvec feature "default" (*) -│ └── pct-str feature "default" -│ └── pct-str v1.2.0 -│ └── utf8-decode feature "default" -│ └── utf8-decode v1.0.1 -├── managed_subscribe feature "default" (command-line) -│ └── managed_subscribe v0.1.0 (/home/ashbeitz/repos/ibeji/core/module/managed_subscribe) -│ ├── common feature "default" (command-line) (*) -│ ├── bytes feature "default" (*) -│ ├── serde feature "default" (*) -│ ├── serde feature "derive" (*) -│ ├── serde_derive feature "default" (*) -│ ├── yaml-rust feature "default" (*) -│ ├── core-protobuf-data-access feature "default" (command-line) (*) -│ ├── prost feature "default" (*) -│ ├── tokio feature "default" (*) -│ ├── tokio feature "macros" (*) -│ ├── tokio feature "rt-multi-thread" (*) -│ ├── log feature "default" (*) -│ ├── tonic feature "default" (*) -│ ├── tower feature "default" (*) -│ ├── dyn-clone feature "default" (*) -│ ├── parking_lot feature "default" (*) -│ ├── strum feature "default" -│ │ ├── strum v0.25.0 -│ │ └── strum feature "std" -│ │ └── strum v0.25.0 -│ └── strum_macros feature "default" -│ └── strum_macros v0.25.1 (proc-macro) -│ ├── proc-macro2 feature "default" (*) -│ ├── quote feature "default" (*) -│ ├── syn feature "default" (*) -│ ├── syn feature "extra-traits" (*) -│ ├── syn feature "parsing" (*) -│ ├── rustversion feature "default" (*) -│ └── heck feature "default" (*) -│ [build-dependencies] -│ └── tonic-build feature "default" (*) -├── strum feature "default" (*) -└── strum_macros feature "default" (*) -[build-dependencies] -└── tonic-build feature "default" (*) - -managed_subscribe v0.1.0 (/home/ashbeitz/repos/ibeji/core/module/managed_subscribe) (*) - -samples-command v0.1.0 (/home/ashbeitz/repos/ibeji/samples/command) -├── serde feature "default" (*) -├── serde_derive feature "default" (*) -├── serde_json feature "default" (*) -├── prost feature "default" (*) -├── tokio feature "default" (*) -├── tokio feature "macros" (*) -├── tokio feature "rt-multi-thread" (*) -├── log feature "default" (*) -├── tonic feature "default" (*) -├── tokio-stream feature "default" (*) -├── parking_lot feature "default" (*) -├── digital-twin-model feature "default" (command-line) -│ └── digital-twin-model v0.1.0 (/home/ashbeitz/repos/ibeji/digital-twin-model) (*) -├── async-std feature "attributes" (*) -├── async-std feature "default" (*) -├── env_logger feature "default" (*) -├── samples-common feature "default" (command-line) -│ ├── samples-common v0.1.0 (/home/ashbeitz/repos/ibeji/samples/common) -│ │ ├── config feature "default" (*) -│ │ ├── serde feature "default" (*) -│ │ ├── serde feature "derive" (*) -│ │ ├── serde_derive feature "default" (*) -│ │ ├── yaml-rust feature "default" (*) -│ │ ├── tokio feature "default" (*) -│ │ ├── log feature "default" (*) -│ │ ├── tonic feature "default" (*) -│ │ └── samples-protobuf-data-access feature "default" (command-line) -│ │ └── samples-protobuf-data-access v1.0.0 (/home/ashbeitz/repos/ibeji/samples/protobuf_data_access) -│ │ ├── serde feature "default" (*) -│ │ ├── serde feature "derive" (*) -│ │ ├── prost feature "default" (*) -│ │ ├── prost-types feature "default" (*) -│ │ ├── tokio feature "default" (*) -│ │ ├── tokio feature "macros" (*) -│ │ ├── tokio feature "rt-multi-thread" (*) -│ │ └── tonic feature "default" (*) -│ │ [build-dependencies] -│ │ └── tonic-build feature "default" (*) -│ └── samples-common feature "yaml" -│ ├── samples-common v0.1.0 (/home/ashbeitz/repos/ibeji/samples/common) (*) -│ └── samples-common feature "yaml-rust" -│ └── samples-common v0.1.0 (/home/ashbeitz/repos/ibeji/samples/common) (*) -├── samples-protobuf-data-access feature "default" (command-line) (*) -├── uuid feature "default" -│ ├── uuid v1.4.1 -│ │ ├── getrandom feature "default" (*) -│ │ ├── rand feature "default" (*) -│ │ └── uuid-macro-internal feature "default" -│ │ └── uuid-macro-internal v1.4.1 (proc-macro) -│ │ ├── proc-macro2 feature "default" (*) -│ │ ├── proc-macro2 feature "span-locations" -│ │ │ └── proc-macro2 v1.0.66 (*) -│ │ ├── quote feature "default" (*) -│ │ └── syn feature "default" (*) -│ └── uuid feature "std" -│ └── uuid v1.4.1 (*) -├── uuid feature "fast-rng" -│ ├── uuid v1.4.1 (*) -│ ├── uuid feature "rand" -│ │ └── uuid v1.4.1 (*) -│ └── uuid feature "rng" -│ ├── uuid v1.4.1 (*) -│ └── uuid feature "getrandom" -│ └── uuid v1.4.1 (*) -├── uuid feature "macro-diagnostics" -│ ├── uuid v1.4.1 (*) -│ └── uuid feature "uuid-macro-internal" -│ └── uuid v1.4.1 (*) -└── uuid feature "v4" - ├── uuid v1.4.1 (*) - └── uuid feature "rng" (*) -[build-dependencies] -└── tonic-build feature "default" (*) - -samples-common v0.1.0 (/home/ashbeitz/repos/ibeji/samples/common) (*) - -samples-managed-subscribe v0.1.0 (/home/ashbeitz/repos/ibeji/samples/managed_subscribe) -├── serde feature "default" (*) -├── serde_derive feature "default" (*) -├── serde_json feature "default" (*) -├── prost feature "default" (*) -├── tokio feature "default" (*) -├── tokio feature "macros" (*) -├── tokio feature "rt-multi-thread" (*) -├── tokio feature "signal" -│ ├── tokio v1.29.1 (*) -│ ├── tokio feature "libc" (*) -│ ├── tokio feature "mio" (*) -│ ├── tokio feature "signal-hook-registry" -│ │ └── tokio v1.29.1 (*) -│ ├── mio feature "net" (*) -│ ├── mio feature "os-ext" (*) -│ └── mio feature "os-poll" (*) -├── log feature "default" (*) -├── tonic feature "default" (*) -├── parking_lot feature "default" (*) -├── url feature "default" (*) -├── digital-twin-model feature "default" (command-line) (*) -├── async-std feature "attributes" (*) -├── async-std feature "default" (*) -├── env_logger feature "default" (*) -├── strum feature "default" (*) -├── strum_macros feature "default" (*) -├── samples-common feature "default" (command-line) (*) -├── samples-protobuf-data-access feature "default" (command-line) (*) -├── uuid feature "default" (*) -├── uuid feature "fast-rng" (*) -├── uuid feature "macro-diagnostics" (*) -├── uuid feature "v4" (*) -└── paho-mqtt feature "default" - ├── paho-mqtt v0.12.1 - │ ├── paho-mqtt-sys v0.8.1 - │ │ └── openssl-sys feature "default" - │ │ └── openssl-sys v0.9.90 - │ │ └── libc feature "default" (*) - │ │ [build-dependencies] - │ │ ├── cc feature "default" - │ │ │ └── cc v1.0.79 - │ │ └── pkg-config feature "default" - │ │ └── pkg-config v0.3.27 - │ │ [build-dependencies] - │ │ └── cmake feature "default" - │ │ └── cmake v0.1.50 - │ │ └── cc feature "default" (*) - │ ├── thiserror feature "default" (*) - │ ├── libc feature "default" (*) - │ ├── log feature "default" (*) - │ ├── futures feature "default" (*) - │ ├── async-channel feature "default" (*) - │ ├── crossbeam-channel feature "default" - │ │ ├── crossbeam-channel v0.5.8 - │ │ │ ├── crossbeam-utils v0.8.16 (*) - │ │ │ └── cfg-if feature "default" (*) - │ │ └── crossbeam-channel feature "std" - │ │ ├── crossbeam-channel v0.5.8 (*) - │ │ ├── crossbeam-utils feature "std" (*) - │ │ └── crossbeam-channel feature "crossbeam-utils" - │ │ └── crossbeam-channel v0.5.8 (*) - │ └── futures-timer feature "default" - │ └── futures-timer v3.0.2 - ├── paho-mqtt feature "bundled" - │ ├── paho-mqtt v0.12.1 (*) - │ └── paho-mqtt-sys feature "bundled" - │ ├── paho-mqtt-sys v0.8.1 (*) - │ └── paho-mqtt-sys feature "cmake" - │ └── paho-mqtt-sys v0.8.1 (*) - └── paho-mqtt feature "ssl" - ├── paho-mqtt v0.12.1 (*) - └── paho-mqtt-sys feature "ssl" - ├── paho-mqtt-sys v0.8.1 (*) - └── paho-mqtt-sys feature "openssl-sys" - └── paho-mqtt-sys v0.8.1 (*) -[build-dependencies] -└── tonic-build feature "default" (*) - -samples-mixed v0.1.0 (/home/ashbeitz/repos/ibeji/samples/mixed) -├── serde feature "default" (*) -├── serde_derive feature "default" (*) -├── serde_json feature "default" (*) -├── prost feature "default" (*) -├── tokio feature "default" (*) -├── tokio feature "macros" (*) -├── tokio feature "rt-multi-thread" (*) -├── log feature "default" (*) -├── tonic feature "default" (*) -├── tokio-stream feature "default" (*) -├── parking_lot feature "default" (*) -├── digital-twin-model feature "default" (command-line) (*) -├── async-std feature "attributes" (*) -├── async-std feature "default" (*) -├── env_logger feature "default" (*) -├── samples-common feature "default" (command-line) (*) -├── samples-protobuf-data-access feature "default" (command-line) (*) -├── uuid feature "default" (*) -├── uuid feature "fast-rng" (*) -├── uuid feature "macro-diagnostics" (*) -└── uuid feature "v4" (*) -[build-dependencies] -└── tonic-build feature "default" (*) - -samples-property v0.1.0 (/home/ashbeitz/repos/ibeji/samples/property) -├── serde feature "default" (*) -├── serde_derive feature "default" (*) -├── serde_json feature "default" (*) -├── prost feature "default" (*) -├── tokio feature "default" (*) -├── tokio feature "macros" (*) -├── tokio feature "rt-multi-thread" (*) -├── tokio feature "signal" (*) -├── log feature "default" (*) -├── tonic feature "default" (*) -├── parking_lot feature "default" (*) -├── url feature "default" (*) -├── digital-twin-model feature "default" (command-line) (*) -├── async-std feature "attributes" (*) -├── async-std feature "default" (*) -├── env_logger feature "default" (*) -├── samples-common feature "default" (command-line) (*) -├── samples-protobuf-data-access feature "default" (command-line) (*) -├── uuid feature "default" (*) -├── uuid feature "fast-rng" (*) -├── uuid feature "macro-diagnostics" (*) -├── uuid feature "v4" (*) -└── paho-mqtt feature "default" (*) -[build-dependencies] -└── tonic-build feature "default" (*) - -samples-protobuf-data-access v1.0.0 (/home/ashbeitz/repos/ibeji/samples/protobuf_data_access) (*) - -samples-seat-massager v0.1.0 (/home/ashbeitz/repos/ibeji/samples/seat_massager) -├── serde feature "default" (*) -├── serde_derive feature "default" (*) -├── serde_json feature "default" (*) -├── tokio feature "default" (*) -├── tokio feature "macros" (*) -├── tokio feature "rt-multi-thread" (*) -├── log feature "default" (*) -├── tonic feature "default" (*) -├── tokio-stream feature "default" (*) -├── parking_lot feature "default" (*) -├── digital-twin-model feature "default" (command-line) (*) -├── async-std feature "attributes" (*) -├── async-std feature "default" (*) -├── env_logger feature "default" (*) -├── samples-common feature "default" (command-line) (*) -└── samples-protobuf-data-access feature "default" (command-line) (*) -[build-dependencies] -└── tonic-build feature "default" (*) - -samples-streaming v0.1.0 (/home/ashbeitz/repos/ibeji/samples/streaming) -├── config feature "default" (*) -├── serde feature "default" (*) -├── serde feature "derive" (*) -├── serde_derive feature "default" (*) -├── serde_json feature "default" (*) -├── yaml-rust feature "default" (*) -├── prost feature "default" (*) -├── tokio feature "default" (*) -├── tokio feature "macros" (*) -├── tokio feature "rt-multi-thread" (*) -├── tokio feature "signal" (*) -├── tokio feature "sync" (*) -├── log feature "default" (*) -├── tonic feature "default" (*) -├── tokio-stream feature "default" (*) -├── parking_lot feature "default" (*) -├── url feature "default" (*) -├── digital-twin-model feature "default" (command-line) (*) -├── async-std feature "attributes" (*) -├── async-std feature "default" (*) -├── env_logger feature "default" (*) -├── samples-common feature "default" (command-line) (*) -├── samples-protobuf-data-access feature "default" (command-line) (*) -├── uuid feature "default" (*) -├── uuid feature "fast-rng" (*) -├── uuid feature "macro-diagnostics" (*) -├── uuid feature "v4" (*) -├── paho-mqtt feature "default" (*) -├── image feature "default" -│ ├── image v0.24.7 -│ │ ├── jpeg-decoder v0.3.0 -│ │ │ └── rayon feature "default" -│ │ │ └── rayon v1.7.0 -│ │ │ ├── either v1.9.0 -│ │ │ └── rayon-core feature "default" -│ │ │ └── rayon-core v1.11.0 -│ │ │ ├── num_cpus feature "default" (*) -│ │ │ ├── crossbeam-utils feature "default" (*) -│ │ │ ├── crossbeam-channel feature "default" (*) -│ │ │ └── crossbeam-deque feature "default" -│ │ │ ├── crossbeam-deque v0.8.3 -│ │ │ │ ├── crossbeam-epoch v0.9.15 -│ │ │ │ │ ├── crossbeam-utils v0.8.16 (*) -│ │ │ │ │ ├── scopeguard v1.2.0 -│ │ │ │ │ ├── cfg-if feature "default" (*) -│ │ │ │ │ └── memoffset feature "default" -│ │ │ │ │ └── memoffset v0.9.0 -│ │ │ │ │ [build-dependencies] -│ │ │ │ │ └── autocfg feature "default" (*) -│ │ │ │ │ [build-dependencies] -│ │ │ │ │ └── autocfg feature "default" (*) -│ │ │ │ ├── crossbeam-utils v0.8.16 (*) -│ │ │ │ └── cfg-if feature "default" (*) -│ │ │ └── crossbeam-deque feature "std" -│ │ │ ├── crossbeam-deque v0.8.3 (*) -│ │ │ ├── crossbeam-utils feature "std" (*) -│ │ │ ├── crossbeam-deque feature "crossbeam-epoch" -│ │ │ │ └── crossbeam-deque v0.8.3 (*) -│ │ │ ├── crossbeam-deque feature "crossbeam-utils" -│ │ │ │ └── crossbeam-deque v0.8.3 (*) -│ │ │ └── crossbeam-epoch feature "std" -│ │ │ ├── crossbeam-epoch v0.9.15 (*) -│ │ │ ├── crossbeam-utils feature "std" (*) -│ │ │ └── crossbeam-epoch feature "alloc" -│ │ │ └── crossbeam-epoch v0.9.15 (*) -│ │ ├── num-rational v0.4.1 -│ │ │ ├── num-integer feature "i128" -│ │ │ │ ├── num-integer v0.1.45 -│ │ │ │ │ └── num-traits v0.2.16 -│ │ │ │ │ [build-dependencies] -│ │ │ │ │ └── autocfg feature "default" (*) -│ │ │ │ │ [build-dependencies] -│ │ │ │ │ └── autocfg feature "default" (*) -│ │ │ │ └── num-traits feature "i128" -│ │ │ │ └── num-traits v0.2.16 (*) -│ │ │ └── num-traits feature "i128" (*) -│ │ │ [build-dependencies] -│ │ │ └── autocfg feature "default" (*) -│ │ ├── bytemuck feature "default" -│ │ │ └── bytemuck v1.13.1 -│ │ ├── bytemuck feature "extern_crate_alloc" -│ │ │ └── bytemuck v1.13.1 -│ │ ├── byteorder feature "default" -│ │ │ ├── byteorder v1.4.3 -│ │ │ └── byteorder feature "std" -│ │ │ └── byteorder v1.4.3 -│ │ ├── color_quant feature "default" -│ │ │ └── color_quant v1.1.0 -│ │ ├── exr feature "default" -│ │ │ └── exr v1.7.0 -│ │ │ ├── smallvec feature "default" (*) -│ │ │ ├── bit_field feature "default" -│ │ │ │ └── bit_field v0.10.2 -│ │ │ ├── flume feature "default" -│ │ │ │ ├── flume v0.10.14 -│ │ │ │ │ ├── futures-core v0.3.28 -│ │ │ │ │ ├── futures-sink v0.3.28 -│ │ │ │ │ ├── pin-project feature "default" (*) -│ │ │ │ │ ├── nanorand feature "default" -│ │ │ │ │ │ ├── nanorand v0.7.0 -│ │ │ │ │ │ │ ├── getrandom feature "default" (*) -│ │ │ │ │ │ │ ├── getrandom feature "js" -│ │ │ │ │ │ │ │ ├── getrandom v0.2.10 (*) -│ │ │ │ │ │ │ │ ├── getrandom feature "js-sys" -│ │ │ │ │ │ │ │ │ └── getrandom v0.2.10 (*) -│ │ │ │ │ │ │ │ └── getrandom feature "wasm-bindgen" -│ │ │ │ │ │ │ │ └── getrandom v0.2.10 (*) -│ │ │ │ │ │ │ └── getrandom feature "rdrand" -│ │ │ │ │ │ │ └── getrandom v0.2.10 (*) -│ │ │ │ │ │ ├── nanorand feature "chacha" -│ │ │ │ │ │ │ └── nanorand v0.7.0 (*) -│ │ │ │ │ │ ├── nanorand feature "pcg64" -│ │ │ │ │ │ │ └── nanorand v0.7.0 (*) -│ │ │ │ │ │ ├── nanorand feature "std" -│ │ │ │ │ │ │ ├── nanorand v0.7.0 (*) -│ │ │ │ │ │ │ └── nanorand feature "alloc" -│ │ │ │ │ │ │ └── nanorand v0.7.0 (*) -│ │ │ │ │ │ ├── nanorand feature "tls" -│ │ │ │ │ │ │ ├── nanorand v0.7.0 (*) -│ │ │ │ │ │ │ ├── nanorand feature "std" (*) -│ │ │ │ │ │ │ └── nanorand feature "wyrand" -│ │ │ │ │ │ │ └── nanorand v0.7.0 (*) -│ │ │ │ │ │ └── nanorand feature "wyrand" (*) -│ │ │ │ │ ├── nanorand feature "getrandom" -│ │ │ │ │ │ └── nanorand v0.7.0 (*) -│ │ │ │ │ ├── spin feature "default" -│ │ │ │ │ │ ├── spin v0.9.8 -│ │ │ │ │ │ │ └── lock_api feature "default" (*) -│ │ │ │ │ │ ├── spin feature "barrier" -│ │ │ │ │ │ │ ├── spin v0.9.8 (*) -│ │ │ │ │ │ │ └── spin feature "mutex" -│ │ │ │ │ │ │ └── spin v0.9.8 (*) -│ │ │ │ │ │ ├── spin feature "lazy" -│ │ │ │ │ │ │ ├── spin v0.9.8 (*) -│ │ │ │ │ │ │ └── spin feature "once" -│ │ │ │ │ │ │ └── spin v0.9.8 (*) -│ │ │ │ │ │ ├── spin feature "lock_api" -│ │ │ │ │ │ │ ├── spin v0.9.8 (*) -│ │ │ │ │ │ │ └── spin feature "lock_api_crate" -│ │ │ │ │ │ │ └── spin v0.9.8 (*) -│ │ │ │ │ │ ├── spin feature "mutex" (*) -│ │ │ │ │ │ ├── spin feature "once" (*) -│ │ │ │ │ │ ├── spin feature "rwlock" -│ │ │ │ │ │ │ └── spin v0.9.8 (*) -│ │ │ │ │ │ └── spin feature "spin_mutex" -│ │ │ │ │ │ ├── spin v0.9.8 (*) -│ │ │ │ │ │ └── spin feature "mutex" (*) -│ │ │ │ │ └── spin feature "mutex" (*) -│ │ │ │ ├── flume feature "async" -│ │ │ │ │ ├── flume v0.10.14 (*) -│ │ │ │ │ ├── flume feature "futures-core" -│ │ │ │ │ │ └── flume v0.10.14 (*) -│ │ │ │ │ ├── flume feature "futures-sink" -│ │ │ │ │ │ └── flume v0.10.14 (*) -│ │ │ │ │ └── flume feature "pin-project" -│ │ │ │ │ └── flume v0.10.14 (*) -│ │ │ │ ├── flume feature "eventual-fairness" -│ │ │ │ │ ├── flume v0.10.14 (*) -│ │ │ │ │ ├── flume feature "async" (*) -│ │ │ │ │ └── flume feature "nanorand" -│ │ │ │ │ └── flume v0.10.14 (*) -│ │ │ │ └── flume feature "select" -│ │ │ │ └── flume v0.10.14 (*) -│ │ │ ├── half feature "default" -│ │ │ │ ├── half v2.2.1 -│ │ │ │ └── half feature "std" -│ │ │ │ ├── half v2.2.1 -│ │ │ │ └── half feature "alloc" -│ │ │ │ └── half v2.2.1 -│ │ │ ├── lebe feature "default" -│ │ │ │ └── lebe v0.5.2 -│ │ │ ├── miniz_oxide feature "default" -│ │ │ │ ├── miniz_oxide v0.7.1 -│ │ │ │ │ ├── adler v1.0.2 -│ │ │ │ │ └── simd-adler32 v0.3.7 -│ │ │ │ └── miniz_oxide feature "with-alloc" -│ │ │ │ └── miniz_oxide v0.7.1 (*) -│ │ │ ├── rayon-core feature "default" (*) -│ │ │ └── zune-inflate feature "zlib" -│ │ │ ├── zune-inflate v0.2.54 -│ │ │ │ └── simd-adler32 v0.3.7 -│ │ │ └── zune-inflate feature "simd-adler32" -│ │ │ └── zune-inflate v0.2.54 (*) -│ │ ├── gif feature "default" -│ │ │ ├── gif v0.12.0 -│ │ │ │ ├── color_quant feature "default" (*) -│ │ │ │ └── weezl feature "default" -│ │ │ │ ├── weezl v0.1.7 -│ │ │ │ └── weezl feature "std" -│ │ │ │ ├── weezl v0.1.7 -│ │ │ │ └── weezl feature "alloc" -│ │ │ │ └── weezl v0.1.7 -│ │ │ ├── gif feature "color_quant" -│ │ │ │ └── gif v0.12.0 (*) -│ │ │ ├── gif feature "raii_no_panic" -│ │ │ │ └── gif v0.12.0 (*) -│ │ │ └── gif feature "std" -│ │ │ └── gif v0.12.0 (*) -│ │ ├── num-traits feature "default" -│ │ │ ├── num-traits v0.2.16 (*) -│ │ │ └── num-traits feature "std" -│ │ │ └── num-traits v0.2.16 (*) -│ │ ├── png feature "default" -│ │ │ └── png v0.17.10 -│ │ │ ├── bitflags feature "default" (*) -│ │ │ ├── miniz_oxide feature "default" (*) -│ │ │ ├── miniz_oxide feature "simd" -│ │ │ │ ├── miniz_oxide v0.7.1 (*) -│ │ │ │ └── miniz_oxide feature "simd-adler32" -│ │ │ │ └── miniz_oxide v0.7.1 (*) -│ │ │ ├── crc32fast feature "default" -│ │ │ │ ├── crc32fast v1.3.2 -│ │ │ │ │ └── cfg-if feature "default" (*) -│ │ │ │ └── crc32fast feature "std" -│ │ │ │ └── crc32fast v1.3.2 (*) -│ │ │ ├── fdeflate feature "default" -│ │ │ │ └── fdeflate v0.3.0 -│ │ │ │ └── simd-adler32 feature "default" -│ │ │ │ ├── simd-adler32 v0.3.7 -│ │ │ │ ├── simd-adler32 feature "const-generics" -│ │ │ │ │ └── simd-adler32 v0.3.7 -│ │ │ │ └── simd-adler32 feature "std" -│ │ │ │ └── simd-adler32 v0.3.7 -│ │ │ └── flate2 feature "default" -│ │ │ ├── flate2 v1.0.27 -│ │ │ │ ├── miniz_oxide feature "with-alloc" (*) -│ │ │ │ └── crc32fast feature "default" (*) -│ │ │ └── flate2 feature "rust_backend" -│ │ │ ├── flate2 v1.0.27 (*) -│ │ │ ├── flate2 feature "any_impl" -│ │ │ │ └── flate2 v1.0.27 (*) -│ │ │ └── flate2 feature "miniz_oxide" -│ │ │ └── flate2 v1.0.27 (*) -│ │ ├── qoi feature "default" -│ │ │ ├── qoi v0.4.1 -│ │ │ │ └── bytemuck feature "default" (*) -│ │ │ └── qoi feature "std" -│ │ │ └── qoi v0.4.1 (*) -│ │ └── tiff feature "default" -│ │ └── tiff v0.9.0 -│ │ ├── jpeg-decoder v0.3.0 (*) -│ │ ├── weezl feature "default" (*) -│ │ └── flate2 feature "default" (*) -│ ├── image feature "bmp" -│ │ └── image v0.24.7 (*) -│ ├── image feature "dds" -│ │ ├── image v0.24.7 (*) -│ │ └── image feature "dxt" -│ │ └── image v0.24.7 (*) -│ ├── image feature "dxt" (*) -│ ├── image feature "farbfeld" -│ │ └── image v0.24.7 (*) -│ ├── image feature "gif" -│ │ └── image v0.24.7 (*) -│ ├── image feature "hdr" -│ │ └── image v0.24.7 (*) -│ ├── image feature "ico" -│ │ ├── image v0.24.7 (*) -│ │ ├── image feature "bmp" (*) -│ │ └── image feature "png" -│ │ └── image v0.24.7 (*) -│ ├── image feature "jpeg" -│ │ └── image v0.24.7 (*) -│ ├── image feature "jpeg_rayon" -│ │ ├── image v0.24.7 (*) -│ │ ├── image feature "jpeg" (*) -│ │ └── jpeg-decoder feature "rayon" -│ │ └── jpeg-decoder v0.3.0 (*) -│ ├── image feature "openexr" -│ │ ├── image v0.24.7 (*) -│ │ └── image feature "exr" -│ │ └── image v0.24.7 (*) -│ ├── image feature "png" (*) -│ ├── image feature "pnm" -│ │ └── image v0.24.7 (*) -│ ├── image feature "qoi" -│ │ └── image v0.24.7 (*) -│ ├── image feature "tga" -│ │ └── image v0.24.7 (*) -│ ├── image feature "tiff" -│ │ └── image v0.24.7 (*) -│ └── image feature "webp" -│ └── image v0.24.7 (*) -└── show-image feature "default" - ├── show-image v0.13.1 - │ ├── indexmap feature "default" (*) - │ ├── futures feature "executor" (*) - │ ├── glam feature "default" - │ │ ├── glam v0.21.3 - │ │ └── glam feature "std" - │ │ └── glam v0.21.3 - │ ├── show-image-macros feature "default" - │ │ └── show-image-macros v0.12.3 (proc-macro) - │ │ ├── proc-macro2 feature "default" (*) - │ │ ├── quote feature "default" (*) - │ │ ├── syn feature "default" (*) - │ │ └── syn feature "full" (*) - │ ├── wgpu feature "default" - │ │ └── wgpu v0.13.1 - │ │ ├── log feature "default" (*) - │ │ ├── parking_lot feature "default" (*) - │ │ ├── smallvec feature "default" (*) - │ │ ├── arrayvec feature "default" - │ │ │ ├── arrayvec v0.7.4 - │ │ │ └── arrayvec feature "std" - │ │ │ └── arrayvec v0.7.4 - │ │ ├── naga feature "default" - │ │ │ └── naga v0.9.0 - │ │ │ ├── thiserror feature "default" (*) - │ │ │ ├── bitflags feature "default" (*) - │ │ │ ├── log feature "default" (*) - │ │ │ ├── indexmap feature "default" (*) - │ │ │ ├── termcolor feature "default" (*) - │ │ │ ├── num-traits feature "default" (*) - │ │ │ ├── bit-set feature "default" - │ │ │ │ ├── bit-set v0.5.3 - │ │ │ │ │ └── bit-vec v0.6.3 - │ │ │ │ └── bit-set feature "std" - │ │ │ │ ├── bit-set v0.5.3 (*) - │ │ │ │ └── bit-vec feature "std" - │ │ │ │ └── bit-vec v0.6.3 - │ │ │ ├── codespan-reporting feature "default" - │ │ │ │ └── codespan-reporting v0.11.1 - │ │ │ │ ├── termcolor feature "default" (*) - │ │ │ │ └── unicode-width feature "default" - │ │ │ │ └── unicode-width v0.1.10 - │ │ │ ├── hexf-parse feature "default" - │ │ │ │ └── hexf-parse v0.2.1 - │ │ │ ├── petgraph feature "default" - │ │ │ │ ├── petgraph v0.6.3 - │ │ │ │ │ ├── fixedbitset v0.4.2 - │ │ │ │ │ ├── indexmap feature "default" (*) - │ │ │ │ │ └── indexmap feature "std" (*) - │ │ │ │ ├── petgraph feature "graphmap" - │ │ │ │ │ └── petgraph v0.6.3 (*) - │ │ │ │ ├── petgraph feature "matrix_graph" - │ │ │ │ │ └── petgraph v0.6.3 (*) - │ │ │ │ └── petgraph feature "stable_graph" - │ │ │ │ └── petgraph v0.6.3 (*) - │ │ │ ├── rustc-hash feature "default" - │ │ │ │ ├── rustc-hash v1.1.0 - │ │ │ │ └── rustc-hash feature "std" - │ │ │ │ └── rustc-hash v1.1.0 - │ │ │ ├── spirv feature "default" - │ │ │ │ └── spirv v0.2.0+1.5.4 - │ │ │ │ ├── num-traits v0.2.16 (*) - │ │ │ │ └── bitflags feature "default" (*) - │ │ │ └── unicode-xid feature "default" - │ │ │ └── unicode-xid v0.2.4 - │ │ ├── raw-window-handle feature "default" - │ │ │ └── raw-window-handle v0.4.3 - │ │ │ └── cty feature "default" - │ │ │ └── cty v0.2.2 - │ │ ├── wgpu-core feature "default" - │ │ │ └── wgpu-core v0.13.2 - │ │ │ ├── profiling v1.0.9 - │ │ │ ├── thiserror feature "default" (*) - │ │ │ ├── bitflags feature "default" (*) - │ │ │ ├── log feature "default" (*) - │ │ │ ├── parking_lot feature "default" (*) - │ │ │ ├── smallvec feature "default" (*) - │ │ │ ├── arrayvec feature "default" (*) - │ │ │ ├── naga feature "default" (*) - │ │ │ ├── naga feature "span" - │ │ │ │ ├── naga v0.9.0 (*) - │ │ │ │ └── naga feature "codespan-reporting" - │ │ │ │ └── naga v0.9.0 (*) - │ │ │ ├── naga feature "validate" - │ │ │ │ └── naga v0.9.0 (*) - │ │ │ ├── naga feature "wgsl-in" - │ │ │ │ ├── naga v0.9.0 (*) - │ │ │ │ ├── naga feature "codespan-reporting" (*) - │ │ │ │ ├── naga feature "hexf-parse" - │ │ │ │ │ └── naga v0.9.0 (*) - │ │ │ │ └── naga feature "unicode-xid" - │ │ │ │ └── naga v0.9.0 (*) - │ │ │ ├── bit-vec feature "default" - │ │ │ │ ├── bit-vec v0.6.3 - │ │ │ │ └── bit-vec feature "std" (*) - │ │ │ ├── codespan-reporting feature "default" (*) - │ │ │ ├── raw-window-handle feature "default" (*) - │ │ │ ├── copyless feature "default" - │ │ │ │ └── copyless v0.1.5 - │ │ │ ├── fxhash feature "default" - │ │ │ │ └── fxhash v0.2.1 - │ │ │ │ └── byteorder feature "default" (*) - │ │ │ ├── wgpu-hal feature "default" - │ │ │ │ └── wgpu-hal v0.13.2 - │ │ │ │ ├── profiling v1.0.9 - │ │ │ │ ├── thiserror feature "default" (*) - │ │ │ │ ├── bitflags feature "default" (*) - │ │ │ │ ├── log feature "default" (*) - │ │ │ │ ├── parking_lot feature "default" (*) - │ │ │ │ ├── arrayvec feature "default" (*) - │ │ │ │ ├── naga feature "default" (*) - │ │ │ │ ├── raw-window-handle feature "default" (*) - │ │ │ │ ├── fxhash feature "default" (*) - │ │ │ │ ├── ash feature "default" - │ │ │ │ │ ├── ash v0.37.3+1.3.251 - │ │ │ │ │ │ └── libloading feature "default" - │ │ │ │ │ │ └── libloading v0.7.4 - │ │ │ │ │ │ └── cfg-if feature "default" (*) - │ │ │ │ │ ├── ash feature "debug" - │ │ │ │ │ │ └── ash v0.37.3+1.3.251 (*) - │ │ │ │ │ └── ash feature "loaded" - │ │ │ │ │ ├── ash v0.37.3+1.3.251 (*) - │ │ │ │ │ └── ash feature "libloading" - │ │ │ │ │ └── ash v0.37.3+1.3.251 (*) - │ │ │ │ ├── libloading feature "default" (*) - │ │ │ │ ├── glow feature "default" - │ │ │ │ │ └── glow v0.11.2 - │ │ │ │ ├── gpu-alloc feature "default" - │ │ │ │ │ ├── gpu-alloc v0.5.4 - │ │ │ │ │ │ ├── bitflags v1.3.2 - │ │ │ │ │ │ └── gpu-alloc-types feature "default" - │ │ │ │ │ │ └── gpu-alloc-types v0.2.0 - │ │ │ │ │ │ └── bitflags v1.3.2 - │ │ │ │ │ └── gpu-alloc feature "std" - │ │ │ │ │ └── gpu-alloc v0.5.4 (*) - │ │ │ │ ├── gpu-descriptor feature "default" - │ │ │ │ │ ├── gpu-descriptor v0.2.3 - │ │ │ │ │ │ ├── bitflags v1.3.2 - │ │ │ │ │ │ ├── hashbrown feature "default" (*) - │ │ │ │ │ │ └── gpu-descriptor-types feature "default" - │ │ │ │ │ │ └── gpu-descriptor-types v0.1.1 - │ │ │ │ │ │ └── bitflags v1.3.2 - │ │ │ │ │ └── gpu-descriptor feature "std" - │ │ │ │ │ └── gpu-descriptor v0.2.3 (*) - │ │ │ │ ├── inplace_it feature "default" - │ │ │ │ │ └── inplace_it v0.3.5 - │ │ │ │ ├── khronos-egl feature "default" - │ │ │ │ │ ├── khronos-egl v4.1.0 - │ │ │ │ │ │ ├── libc feature "default" (*) - │ │ │ │ │ │ └── libloading feature "default" (*) - │ │ │ │ │ └── khronos-egl feature "1_5" - │ │ │ │ │ ├── khronos-egl v4.1.0 (*) - │ │ │ │ │ └── khronos-egl feature "1_4" - │ │ │ │ │ ├── khronos-egl v4.1.0 (*) - │ │ │ │ │ └── khronos-egl feature "1_3" - │ │ │ │ │ ├── khronos-egl v4.1.0 (*) - │ │ │ │ │ └── khronos-egl feature "1_2" - │ │ │ │ │ ├── khronos-egl v4.1.0 (*) - │ │ │ │ │ └── khronos-egl feature "1_1" - │ │ │ │ │ ├── khronos-egl v4.1.0 (*) - │ │ │ │ │ └── khronos-egl feature "1_0" - │ │ │ │ │ └── khronos-egl v4.1.0 (*) - │ │ │ │ ├── khronos-egl feature "dynamic" - │ │ │ │ │ ├── khronos-egl v4.1.0 (*) - │ │ │ │ │ └── khronos-egl feature "libloading" - │ │ │ │ │ └── khronos-egl v4.1.0 (*) - │ │ │ │ ├── renderdoc-sys feature "default" - │ │ │ │ │ └── renderdoc-sys v0.7.1 - │ │ │ │ └── wgpu-types feature "default" - │ │ │ │ └── wgpu-types v0.13.2 - │ │ │ │ └── bitflags feature "default" (*) - │ │ │ ├── wgpu-hal feature "gles" - │ │ │ │ ├── wgpu-hal v0.13.2 (*) - │ │ │ │ ├── naga feature "glsl-out" - │ │ │ │ │ └── naga v0.9.0 (*) - │ │ │ │ ├── wgpu-hal feature "egl" - │ │ │ │ │ └── wgpu-hal v0.13.2 (*) - │ │ │ │ ├── wgpu-hal feature "glow" - │ │ │ │ │ └── wgpu-hal v0.13.2 (*) - │ │ │ │ └── wgpu-hal feature "libloading" - │ │ │ │ └── wgpu-hal v0.13.2 (*) - │ │ │ ├── wgpu-hal feature "renderdoc" - │ │ │ │ ├── wgpu-hal v0.13.2 (*) - │ │ │ │ ├── wgpu-hal feature "libloading" (*) - │ │ │ │ └── wgpu-hal feature "renderdoc-sys" - │ │ │ │ └── wgpu-hal v0.13.2 (*) - │ │ │ ├── wgpu-hal feature "vulkan" - │ │ │ │ ├── wgpu-hal v0.13.2 (*) - │ │ │ │ ├── naga feature "spv-out" - │ │ │ │ │ ├── naga v0.9.0 (*) - │ │ │ │ │ └── naga feature "spirv" - │ │ │ │ │ └── naga v0.9.0 (*) - │ │ │ │ ├── wgpu-hal feature "ash" - │ │ │ │ │ └── wgpu-hal v0.13.2 (*) - │ │ │ │ ├── wgpu-hal feature "gpu-alloc" - │ │ │ │ │ └── wgpu-hal v0.13.2 (*) - │ │ │ │ ├── wgpu-hal feature "gpu-descriptor" - │ │ │ │ │ └── wgpu-hal v0.13.2 (*) - │ │ │ │ ├── wgpu-hal feature "inplace_it" - │ │ │ │ │ └── wgpu-hal v0.13.2 (*) - │ │ │ │ └── wgpu-hal feature "libloading" (*) - │ │ │ └── wgpu-types feature "default" (*) - │ │ │ [build-dependencies] - │ │ │ └── cfg_aliases feature "default" - │ │ │ └── cfg_aliases v0.1.1 - │ │ ├── wgpu-core feature "raw-window-handle" - │ │ │ └── wgpu-core v0.13.2 (*) - │ │ ├── wgpu-hal feature "default" (*) - │ │ └── wgpu-types feature "default" (*) - │ ├── wgpu feature "spirv" - │ │ ├── wgpu v0.13.1 (*) - │ │ ├── wgpu feature "naga" - │ │ │ └── wgpu v0.13.1 (*) - │ │ └── naga feature "spv-in" - │ │ ├── naga v0.9.0 (*) - │ │ ├── naga feature "petgraph" - │ │ │ └── naga v0.9.0 (*) - │ │ └── naga feature "spirv" (*) - │ └── winit feature "default" - │ ├── winit v0.27.5 - │ │ ├── once_cell feature "default" (*) - │ │ ├── bitflags feature "default" (*) - │ │ ├── libc feature "default" (*) - │ │ ├── mio feature "default" - │ │ │ ├── mio v0.8.8 (*) - │ │ │ └── mio feature "log" - │ │ │ └── mio v0.8.8 (*) - │ │ ├── mio feature "os-ext" (*) - │ │ ├── log feature "default" (*) - │ │ ├── percent-encoding feature "default" (*) - │ │ ├── parking_lot feature "default" (*) - │ │ ├── raw-window-handle feature "default" (*) - │ │ ├── instant feature "default" - │ │ │ └── instant v0.1.12 - │ │ │ └── cfg-if feature "default" (*) - │ │ ├── instant feature "wasm-bindgen" - │ │ │ ├── instant v0.1.12 (*) - │ │ │ ├── instant feature "js-sys" - │ │ │ │ └── instant v0.1.12 (*) - │ │ │ ├── instant feature "wasm-bindgen_rs" - │ │ │ │ └── instant v0.1.12 (*) - │ │ │ └── instant feature "web-sys" - │ │ │ └── instant v0.1.12 (*) - │ │ ├── raw-window-handle feature "default" - │ │ │ └── raw-window-handle v0.5.2 - │ │ ├── sctk-adwaita feature "default" - │ │ │ └── sctk-adwaita v0.4.3 - │ │ │ ├── log feature "default" (*) - │ │ │ ├── crossfont feature "default" - │ │ │ │ └── crossfont v0.5.1 - │ │ │ │ ├── libc feature "default" (*) - │ │ │ │ ├── log feature "default" (*) - │ │ │ │ ├── foreign-types feature "default" - │ │ │ │ │ ├── foreign-types v0.5.0 - │ │ │ │ │ │ ├── foreign-types-macros feature "default" - │ │ │ │ │ │ │ └── foreign-types-macros v0.2.3 (proc-macro) - │ │ │ │ │ │ │ ├── proc-macro2 feature "default" (*) - │ │ │ │ │ │ │ ├── quote feature "default" (*) - │ │ │ │ │ │ │ ├── syn feature "default" (*) - │ │ │ │ │ │ │ └── syn feature "full" (*) - │ │ │ │ │ │ └── foreign-types-shared feature "default" - │ │ │ │ │ │ └── foreign-types-shared v0.3.1 - │ │ │ │ │ └── foreign-types feature "std" - │ │ │ │ │ ├── foreign-types v0.5.0 (*) - │ │ │ │ │ └── foreign-types-macros feature "std" - │ │ │ │ │ └── foreign-types-macros v0.2.3 (proc-macro) (*) - │ │ │ │ ├── freetype-rs feature "default" - │ │ │ │ │ └── freetype-rs v0.26.0 - │ │ │ │ │ ├── bitflags feature "default" (*) - │ │ │ │ │ ├── libc feature "default" (*) - │ │ │ │ │ └── freetype-sys feature "default" - │ │ │ │ │ └── freetype-sys v0.13.1 - │ │ │ │ │ └── libc feature "default" (*) - │ │ │ │ │ [build-dependencies] - │ │ │ │ │ ├── cmake feature "default" (*) - │ │ │ │ │ └── pkg-config feature "default" (*) - │ │ │ │ └── servo-fontconfig feature "default" - │ │ │ │ └── servo-fontconfig v0.5.1 - │ │ │ │ ├── libc feature "default" (*) - │ │ │ │ └── servo-fontconfig-sys feature "default" - │ │ │ │ └── servo-fontconfig-sys v5.1.0 - │ │ │ │ ├── freetype-sys feature "default" (*) - │ │ │ │ └── expat-sys feature "default" - │ │ │ │ └── expat-sys v2.1.6 - │ │ │ │ [build-dependencies] - │ │ │ │ ├── cmake feature "default" (*) - │ │ │ │ └── pkg-config feature "default" (*) - │ │ │ │ [build-dependencies] - │ │ │ │ └── pkg-config feature "default" (*) - │ │ │ │ [build-dependencies] - │ │ │ │ └── pkg-config feature "default" (*) - │ │ │ ├── crossfont feature "force_system_fontconfig" - │ │ │ │ ├── crossfont v0.5.1 (*) - │ │ │ │ └── servo-fontconfig feature "force_system_lib" - │ │ │ │ ├── servo-fontconfig v0.5.1 (*) - │ │ │ │ └── servo-fontconfig-sys feature "force_system_lib" - │ │ │ │ └── servo-fontconfig-sys v5.1.0 (*) - │ │ │ ├── smithay-client-toolkit feature "default" - │ │ │ │ ├── smithay-client-toolkit v0.16.0 - │ │ │ │ │ ├── lazy_static feature "default" (*) - │ │ │ │ │ ├── bitflags feature "default" (*) - │ │ │ │ │ ├── log feature "default" (*) - │ │ │ │ │ ├── calloop feature "default" - │ │ │ │ │ │ └── calloop v0.10.6 - │ │ │ │ │ │ ├── thiserror feature "default" (*) - │ │ │ │ │ │ ├── bitflags feature "default" (*) - │ │ │ │ │ │ ├── log feature "default" (*) - │ │ │ │ │ │ ├── nix feature "event" - │ │ │ │ │ │ │ └── nix v0.25.1 - │ │ │ │ │ │ │ ├── cfg-if feature "default" (*) - │ │ │ │ │ │ │ ├── bitflags feature "default" (*) - │ │ │ │ │ │ │ ├── libc feature "default" (*) - │ │ │ │ │ │ │ ├── libc feature "extra_traits" - │ │ │ │ │ │ │ │ └── libc v0.2.147 - │ │ │ │ │ │ │ └── memoffset feature "default" - │ │ │ │ │ │ │ └── memoffset v0.6.5 - │ │ │ │ │ │ │ [build-dependencies] - │ │ │ │ │ │ │ └── autocfg feature "default" (*) - │ │ │ │ │ │ │ [build-dependencies] - │ │ │ │ │ │ │ └── autocfg feature "default" (*) - │ │ │ │ │ │ ├── nix feature "fs" - │ │ │ │ │ │ │ └── nix v0.25.1 (*) - │ │ │ │ │ │ ├── nix feature "signal" - │ │ │ │ │ │ │ ├── nix v0.25.1 (*) - │ │ │ │ │ │ │ └── nix feature "process" - │ │ │ │ │ │ │ └── nix v0.25.1 (*) - │ │ │ │ │ │ ├── nix feature "socket" - │ │ │ │ │ │ │ ├── nix v0.25.1 (*) - │ │ │ │ │ │ │ └── nix feature "memoffset" - │ │ │ │ │ │ │ └── nix v0.25.1 (*) - │ │ │ │ │ │ ├── nix feature "time" - │ │ │ │ │ │ │ └── nix v0.25.1 (*) - │ │ │ │ │ │ ├── slotmap feature "default" - │ │ │ │ │ │ │ ├── slotmap v1.0.6 - │ │ │ │ │ │ │ │ [build-dependencies] - │ │ │ │ │ │ │ │ └── version_check feature "default" (*) - │ │ │ │ │ │ │ └── slotmap feature "std" - │ │ │ │ │ │ │ └── slotmap v1.0.6 (*) - │ │ │ │ │ │ └── vec_map feature "default" - │ │ │ │ │ │ └── vec_map v0.8.2 - │ │ │ │ │ ├── dlib feature "default" - │ │ │ │ │ │ └── dlib v0.5.2 - │ │ │ │ │ │ └── libloading feature "default" - │ │ │ │ │ │ └── libloading v0.8.0 - │ │ │ │ │ │ └── cfg-if feature "default" (*) - │ │ │ │ │ ├── memmap2 feature "default" - │ │ │ │ │ │ └── memmap2 v0.5.10 - │ │ │ │ │ │ └── libc feature "default" (*) - │ │ │ │ │ ├── nix feature "fs" - │ │ │ │ │ │ └── nix v0.24.3 - │ │ │ │ │ │ ├── cfg-if feature "default" (*) - │ │ │ │ │ │ ├── bitflags feature "default" (*) - │ │ │ │ │ │ ├── libc feature "default" (*) - │ │ │ │ │ │ ├── libc feature "extra_traits" (*) - │ │ │ │ │ │ └── memoffset feature "default" (*) - │ │ │ │ │ ├── nix feature "mman" - │ │ │ │ │ │ └── nix v0.24.3 (*) - │ │ │ │ │ ├── wayland-client feature "default" - │ │ │ │ │ │ └── wayland-client v0.29.5 - │ │ │ │ │ │ ├── bitflags feature "default" (*) - │ │ │ │ │ │ ├── libc feature "default" (*) - │ │ │ │ │ │ ├── nix feature "fs" (*) - │ │ │ │ │ │ ├── nix feature "poll" - │ │ │ │ │ │ │ └── nix v0.24.3 (*) - │ │ │ │ │ │ ├── downcast-rs feature "default" - │ │ │ │ │ │ │ ├── downcast-rs v1.2.0 - │ │ │ │ │ │ │ └── downcast-rs feature "std" - │ │ │ │ │ │ │ └── downcast-rs v1.2.0 - │ │ │ │ │ │ ├── scoped-tls feature "default" - │ │ │ │ │ │ │ └── scoped-tls v1.0.1 - │ │ │ │ │ │ ├── wayland-commons feature "default" - │ │ │ │ │ │ │ └── wayland-commons v0.29.5 - │ │ │ │ │ │ │ ├── once_cell feature "default" (*) - │ │ │ │ │ │ │ ├── smallvec feature "default" (*) - │ │ │ │ │ │ │ ├── nix feature "fs" (*) - │ │ │ │ │ │ │ ├── nix feature "socket" - │ │ │ │ │ │ │ │ ├── nix v0.24.3 (*) - │ │ │ │ │ │ │ │ └── nix feature "memoffset" - │ │ │ │ │ │ │ │ └── nix v0.24.3 (*) - │ │ │ │ │ │ │ ├── nix feature "uio" - │ │ │ │ │ │ │ │ └── nix v0.24.3 (*) - │ │ │ │ │ │ │ └── wayland-sys feature "default" - │ │ │ │ │ │ │ └── wayland-sys v0.29.5 - │ │ │ │ │ │ │ ├── lazy_static feature "default" (*) - │ │ │ │ │ │ │ └── dlib feature "default" (*) - │ │ │ │ │ │ │ [build-dependencies] - │ │ │ │ │ │ │ └── pkg-config feature "default" (*) - │ │ │ │ │ │ └── wayland-sys feature "default" (*) - │ │ │ │ │ │ [build-dependencies] - │ │ │ │ │ │ └── wayland-scanner feature "default" - │ │ │ │ │ │ └── wayland-scanner v0.29.5 - │ │ │ │ │ │ ├── proc-macro2 feature "default" (*) - │ │ │ │ │ │ ├── quote feature "default" (*) - │ │ │ │ │ │ └── xml-rs feature "default" - │ │ │ │ │ │ └── xml-rs v0.8.16 - │ │ │ │ │ ├── wayland-cursor feature "default" - │ │ │ │ │ │ └── wayland-cursor v0.29.5 - │ │ │ │ │ │ ├── nix feature "fs" (*) - │ │ │ │ │ │ ├── nix feature "mman" (*) - │ │ │ │ │ │ ├── wayland-client feature "default" (*) - │ │ │ │ │ │ └── xcursor feature "default" - │ │ │ │ │ │ └── xcursor v0.3.4 - │ │ │ │ │ │ └── nom feature "default" (*) - │ │ │ │ │ ├── wayland-protocols feature "client" - │ │ │ │ │ │ ├── wayland-protocols v0.29.5 - │ │ │ │ │ │ │ ├── bitflags feature "default" (*) - │ │ │ │ │ │ │ ├── wayland-client feature "default" (*) - │ │ │ │ │ │ │ └── wayland-commons feature "default" (*) - │ │ │ │ │ │ │ [build-dependencies] - │ │ │ │ │ │ │ └── wayland-scanner feature "default" (*) - │ │ │ │ │ │ └── wayland-protocols feature "wayland-client" - │ │ │ │ │ │ └── wayland-protocols v0.29.5 (*) - │ │ │ │ │ ├── wayland-protocols feature "default" - │ │ │ │ │ │ └── wayland-protocols v0.29.5 (*) - │ │ │ │ │ └── wayland-protocols feature "unstable_protocols" - │ │ │ │ │ └── wayland-protocols v0.29.5 (*) - │ │ │ │ │ [build-dependencies] - │ │ │ │ │ └── pkg-config feature "default" (*) - │ │ │ │ ├── smithay-client-toolkit feature "calloop" - │ │ │ │ │ └── smithay-client-toolkit v0.16.0 (*) - │ │ │ │ └── smithay-client-toolkit feature "dlopen" - │ │ │ │ ├── smithay-client-toolkit v0.16.0 (*) - │ │ │ │ └── wayland-client feature "dlopen" - │ │ │ │ ├── wayland-client v0.29.5 (*) - │ │ │ │ ├── wayland-client feature "use_system_lib" - │ │ │ │ │ ├── wayland-client v0.29.5 (*) - │ │ │ │ │ ├── wayland-client feature "scoped-tls" - │ │ │ │ │ │ └── wayland-client v0.29.5 (*) - │ │ │ │ │ └── wayland-sys feature "client" - │ │ │ │ │ ├── wayland-sys v0.29.5 (*) - │ │ │ │ │ └── wayland-sys feature "dlib" - │ │ │ │ │ └── wayland-sys v0.29.5 (*) - │ │ │ │ └── wayland-sys feature "dlopen" - │ │ │ │ ├── wayland-sys v0.29.5 (*) - │ │ │ │ ├── wayland-sys feature "dlib" (*) - │ │ │ │ └── wayland-sys feature "lazy_static" - │ │ │ │ └── wayland-sys v0.29.5 (*) - │ │ │ ├── tiny-skia feature "default" - │ │ │ │ ├── tiny-skia v0.7.0 - │ │ │ │ │ ├── arrayvec v0.5.2 - │ │ │ │ │ ├── tiny-skia-path v0.7.0 - │ │ │ │ │ │ ├── bytemuck feature "default" (*) - │ │ │ │ │ │ └── arrayref feature "default" - │ │ │ │ │ │ └── arrayref v0.3.7 - │ │ │ │ │ ├── cfg-if feature "default" (*) - │ │ │ │ │ ├── bytemuck feature "default" (*) - │ │ │ │ │ ├── png feature "default" (*) - │ │ │ │ │ ├── arrayref feature "default" (*) - │ │ │ │ │ ├── safe_arch feature "bytemuck" - │ │ │ │ │ │ └── safe_arch v0.5.2 - │ │ │ │ │ │ └── bytemuck feature "default" (*) - │ │ │ │ │ └── safe_arch feature "default" - │ │ │ │ │ └── safe_arch v0.5.2 (*) - │ │ │ │ ├── tiny-skia feature "png-format" - │ │ │ │ │ ├── tiny-skia v0.7.0 (*) - │ │ │ │ │ ├── tiny-skia feature "png" - │ │ │ │ │ │ └── tiny-skia v0.7.0 (*) - │ │ │ │ │ └── tiny-skia feature "std" - │ │ │ │ │ ├── tiny-skia v0.7.0 (*) - │ │ │ │ │ └── tiny-skia-path feature "std" - │ │ │ │ │ └── tiny-skia-path v0.7.0 (*) - │ │ │ │ ├── tiny-skia feature "simd" - │ │ │ │ │ ├── tiny-skia v0.7.0 (*) - │ │ │ │ │ └── tiny-skia feature "safe_arch" - │ │ │ │ │ └── tiny-skia v0.7.0 (*) - │ │ │ │ └── tiny-skia feature "std" (*) - │ │ │ ├── tiny-skia feature "simd" (*) - │ │ │ └── tiny-skia feature "std" (*) - │ │ ├── smithay-client-toolkit feature "calloop" (*) - │ │ ├── wayland-client feature "use_system_lib" (*) - │ │ ├── wayland-protocols feature "default" (*) - │ │ ├── wayland-protocols feature "staging_protocols" - │ │ │ └── wayland-protocols v0.29.5 (*) - │ │ └── x11-dl feature "default" - │ │ └── x11-dl v2.21.0 - │ │ ├── once_cell feature "default" (*) - │ │ └── libc feature "default" (*) - │ │ [build-dependencies] - │ │ └── pkg-config feature "default" (*) - │ ├── winit feature "wayland" - │ │ ├── winit v0.27.5 (*) - │ │ ├── winit feature "sctk" - │ │ │ └── winit v0.27.5 (*) - │ │ ├── winit feature "wayland-client" - │ │ │ └── winit v0.27.5 (*) - │ │ └── winit feature "wayland-protocols" - │ │ └── winit v0.27.5 (*) - │ ├── winit feature "wayland-csd-adwaita" - │ │ ├── winit v0.27.5 (*) - │ │ ├── winit feature "sctk-adwaita" - │ │ │ └── winit v0.27.5 (*) - │ │ └── sctk-adwaita feature "title" - │ │ ├── sctk-adwaita v0.4.3 (*) - │ │ └── sctk-adwaita feature "crossfont" - │ │ └── sctk-adwaita v0.4.3 (*) - │ ├── winit feature "wayland-dlopen" - │ │ ├── winit v0.27.5 (*) - │ │ ├── winit feature "sctk" (*) - │ │ ├── winit feature "wayland-client" (*) - │ │ ├── smithay-client-toolkit feature "dlopen" (*) - │ │ └── wayland-client feature "dlopen" (*) - │ └── winit feature "x11" - │ ├── winit v0.27.5 (*) - │ ├── winit feature "mio" - │ │ └── winit v0.27.5 (*) - │ ├── winit feature "parking_lot" - │ │ └── winit v0.27.5 (*) - │ ├── winit feature "percent-encoding" - │ │ └── winit v0.27.5 (*) - │ └── winit feature "x11-dl" - │ └── winit v0.27.5 (*) - │ [build-dependencies] - │ └── rustc_version feature "default" - │ └── rustc_version v0.4.0 - │ └── semver feature "default" - │ ├── semver v1.0.18 - │ └── semver feature "std" - │ └── semver v1.0.18 - └── show-image feature "macros" - ├── show-image v0.13.1 (*) - └── show-image feature "show-image-macros" - └── show-image v0.13.1 (*) -[build-dependencies] -└── tonic-build feature "default" (*) diff --git a/tools/notice_generation.sh b/tools/notice_generation.sh index 54e0aa2a..bbedc4e1 100755 --- a/tools/notice_generation.sh +++ b/tools/notice_generation.sh @@ -38,7 +38,7 @@ cargo about generate --workspace devops/cg/about.hbs --config devops/cg/about.to DOTNET_SRC_DIRECTORY="dtdl-tools/" echo "Appending .NET Third Party licenses to $NOTICE_FILENAME" -./tools/dotnet_notice_generation.sh $NOTICE_FILENAME $CLOUD_CONNECTORS_AZURE_DIRECTORY ./devops/cg/license_url_to_type.json +./tools/dotnet_notice_generation.sh $NOTICE_FILENAME $DOTNET_SRC_DIRECTORY ./devops/cg/license_url_to_type.json if [ -z "$(git diff --name-only $NOTICE_FILENAME)" ] then From e0f0bce7abb8f15159fca97e77bc3874c6048761 Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:09:46 -0700 Subject: [PATCH 03/28] Removed DTDL Parser --- dtdl-tools/build.rs | 11 +++-------- dtdl-tools/src/dtdl-validator/licenses.md | 5 ----- dtdl-tools/src/lib.rs | 16 +++++++++------- 3 files changed, 12 insertions(+), 20 deletions(-) delete mode 100644 dtdl-tools/src/dtdl-validator/licenses.md diff --git a/dtdl-tools/build.rs b/dtdl-tools/build.rs index c7ece626..6284fafd 100644 --- a/dtdl-tools/build.rs +++ b/dtdl-tools/build.rs @@ -10,16 +10,11 @@ fn main() { const DOTNET_COMMAND: &str = "dotnet"; const DOTNET_BUILD_ARG: &str = "build"; - const CSPROJ_PATHS: &[&str] = &[ - "src/dtdl-validator/dtdl-validator.csproj", - ]; + const CSPROJ_PATHS: &[&str] = &["src/dtdl-validator/dtdl-validator.csproj"]; for csproj in CSPROJ_PATHS { - let output = Command::new(DOTNET_COMMAND) - .arg(DOTNET_BUILD_ARG) - .arg(csproj) - .output() - .unwrap(); + let output = + Command::new(DOTNET_COMMAND).arg(DOTNET_BUILD_ARG).arg(csproj).output().unwrap(); if !output.status.success() { panic!("Failed to run due to {output:?}"); diff --git a/dtdl-tools/src/dtdl-validator/licenses.md b/dtdl-tools/src/dtdl-validator/licenses.md deleted file mode 100644 index b69c41a8..00000000 --- a/dtdl-tools/src/dtdl-validator/licenses.md +++ /dev/null @@ -1,5 +0,0 @@ - | Reference | Version | License Type | License | - | ----------------------------------------- | ------------------- | ------------ | ------------------------------ | - | DTDLParser | 1.0.52 | MIT | https://licenses.nuget.org/MIT | - | System.CommandLine | 2.0.0-beta4.22272.1 | MIT | https://licenses.nuget.org/MIT | - | System.CommandLine.NamingConventionBinder | 2.0.0-beta4.22272.1 | MIT | https://licenses.nuget.org/MIT | diff --git a/dtdl-tools/src/lib.rs b/dtdl-tools/src/lib.rs index fbb3db91..4cf40029 100644 --- a/dtdl-tools/src/lib.rs +++ b/dtdl-tools/src/lib.rs @@ -7,7 +7,7 @@ #[cfg(test)] mod digital_twins_connector_dotnet_tests { use std::io::{self, Write}; - use std::path::Path; + use std::path::Path; use std::process::Command; // The manifest directory is the directory that contains the Cargo.toml file for this crate. @@ -16,22 +16,24 @@ mod digital_twins_connector_dotnet_tests { const DTDL_VALIDATOR_FILENAME: &str = "dtdl-validator"; const DTDL_VALIDATOR_BIN_DIR: &str = "target/debug/dtdl-validator/bin/Debug/net7.0"; const DTDL_VALIDATOR_DIR_OPTION: &str = "-d"; - const DTDL_VALIDATOR_EXT_OPTION: &str = "-e"; + const DTDL_VALIDATOR_EXT_OPTION: &str = "-e"; /// Validate DTDL files. - /// + /// /// # Arguments /// * `directory` - The directory that contains the DTDL files that you wish to validate. /// * `extension` - The file extension that the DTDL files use. fn validate_dtdl_files(directory: &str, extension: &str) -> bool { + let dtdl_validator_command_path = Path::new(MANIFEST_DIR) + .join("..") + .join(DTDL_VALIDATOR_BIN_DIR) + .join(DTDL_VALIDATOR_FILENAME); - let dtdl_validator_command_path = Path::new(MANIFEST_DIR).join("..").join(DTDL_VALIDATOR_BIN_DIR).join(DTDL_VALIDATOR_FILENAME); - let dtdl_validator_output = Command::new(dtdl_validator_command_path) .arg(DTDL_VALIDATOR_DIR_OPTION) .arg(directory) .arg(DTDL_VALIDATOR_EXT_OPTION) - .arg(extension) + .arg(extension) .output() .unwrap(); @@ -46,4 +48,4 @@ mod digital_twins_connector_dotnet_tests { fn validate_digital_twin_model_dtdl_files() { assert!(validate_dtdl_files("../digital-twin-model/dtdl", "json")); } -} \ No newline at end of file +} From eb8e8d2f1e8eb21342ce67a79be7a680bc16f8da Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:14:36 -0700 Subject: [PATCH 04/28] Removed DTDL Parser --- .github/workflows/rust-ci.yml | 2 +- dtdl-tools/src/dtdl-validator/DtdlValidator.cs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index d6362598..17a98921 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -27,7 +27,7 @@ jobs: rustup component add rustfmt clippy - name: Cache Dependencies uses: Swatinem/rust-cache@v2 - - run: cargo check --workspace --locked + - run: cargo check --workspace - run: cargo clippy --all-targets --all-features --workspace --no-deps -- -D warnings - run: cargo fmt --all -- --check - name: Run doctest only diff --git a/dtdl-tools/src/dtdl-validator/DtdlValidator.cs b/dtdl-tools/src/dtdl-validator/DtdlValidator.cs index 8c9ebd52..87c865cb 100644 --- a/dtdl-tools/src/dtdl-validator/DtdlValidator.cs +++ b/dtdl-tools/src/dtdl-validator/DtdlValidator.cs @@ -58,7 +58,7 @@ static int ValidateDtdl(DirectoryInfo directory, String extension) { Console.WriteLine($"{file} - failed"); foreach (var error in ex.Errors) { - Console.WriteLine($" {error}"); + Console.WriteLine($" {error}"); } failureOccured = true; } @@ -81,7 +81,7 @@ static async Task Main(string[] args) "-d", getDefaultValue: () => new DirectoryInfo(Directory.GetCurrentDirectory()), description: "The directory that contains the DTDL files."); - var extensionOption = + var extensionOption = new Option( "-e", getDefaultValue: () => "json", @@ -92,11 +92,11 @@ static async Task Main(string[] args) var cmd = new RootCommand(); cmd.AddOption(directoryOption); cmd.AddOption(extensionOption); - cmd.SetHandler((directory, extension) => - { - exitCode = ValidateDtdl(directory!, extension!); + cmd.SetHandler((directory, extension) => + { + exitCode = ValidateDtdl(directory!, extension!); }, - directoryOption, extensionOption); + directoryOption, extensionOption); await cmd.InvokeAsync(args); From 2a6bd59d48e7989eab729b7133ae5f48a7275e4e Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:27:23 -0700 Subject: [PATCH 05/28] Removed DTDL Parser --- core/invehicle-digital-twin/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/invehicle-digital-twin/src/main.rs b/core/invehicle-digital-twin/src/main.rs index 98d6d9b4..4b299310 100644 --- a/core/invehicle-digital-twin/src/main.rs +++ b/core/invehicle-digital-twin/src/main.rs @@ -7,7 +7,7 @@ // Add a new feature to all() so the use statement is active for the feature. // ex. #[cfg(all(feature = "feature_1", feature = "feature_2"))] -#[cfg(all(feature = "managed_subscribe"))] +#[cfg(feature = "managed_subscribe")] use common::grpc_interceptor::GrpcInterceptorLayer; #[cfg(feature = "managed_subscribe")] From 97257f16931be4ea61d5740a7262237b5c8cc50d Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:33:07 -0700 Subject: [PATCH 06/28] Removed DTDL Parser --- core/invehicle-digital-twin/src/main.rs | 2 -- dtdl-tools/src/lib.rs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/core/invehicle-digital-twin/src/main.rs b/core/invehicle-digital-twin/src/main.rs index 4b299310..e266f111 100644 --- a/core/invehicle-digital-twin/src/main.rs +++ b/core/invehicle-digital-twin/src/main.rs @@ -5,8 +5,6 @@ // Module references behind feature flags. Add any necessary module references here. // Start: Module references. -// Add a new feature to all() so the use statement is active for the feature. -// ex. #[cfg(all(feature = "feature_1", feature = "feature_2"))] #[cfg(feature = "managed_subscribe")] use common::grpc_interceptor::GrpcInterceptorLayer; diff --git a/dtdl-tools/src/lib.rs b/dtdl-tools/src/lib.rs index 4cf40029..da072c14 100644 --- a/dtdl-tools/src/lib.rs +++ b/dtdl-tools/src/lib.rs @@ -41,7 +41,7 @@ mod digital_twins_connector_dotnet_tests { io::stdout().write_all(&dtdl_validator_output.stdout).unwrap(); } - return dtdl_validator_output.status.success(); + dtdl_validator_output.status.success() } #[test] From 8882f1d9b763cbbdde6cfe9f8a6026e14df51cf4 Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:37:20 -0700 Subject: [PATCH 07/28] Removed DTDL Parser --- core/invehicle-digital-twin/src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/invehicle-digital-twin/src/main.rs b/core/invehicle-digital-twin/src/main.rs index e266f111..4b299310 100644 --- a/core/invehicle-digital-twin/src/main.rs +++ b/core/invehicle-digital-twin/src/main.rs @@ -5,6 +5,8 @@ // Module references behind feature flags. Add any necessary module references here. // Start: Module references. +// Add a new feature to all() so the use statement is active for the feature. +// ex. #[cfg(all(feature = "feature_1", feature = "feature_2"))] #[cfg(feature = "managed_subscribe")] use common::grpc_interceptor::GrpcInterceptorLayer; From 0ac723f041cdd38f45058467ce8532b5cc3f83cf Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:39:23 -0700 Subject: [PATCH 08/28] Removed DTDL Parser --- core/invehicle-digital-twin/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/invehicle-digital-twin/src/main.rs b/core/invehicle-digital-twin/src/main.rs index 4b299310..2b8f7eff 100644 --- a/core/invehicle-digital-twin/src/main.rs +++ b/core/invehicle-digital-twin/src/main.rs @@ -7,7 +7,7 @@ // Add a new feature to all() so the use statement is active for the feature. // ex. #[cfg(all(feature = "feature_1", feature = "feature_2"))] -#[cfg(feature = "managed_subscribe")] +#[cfg(any(feature = "managed_subscribe")`)] use common::grpc_interceptor::GrpcInterceptorLayer; #[cfg(feature = "managed_subscribe")] From 516b85edba1c0b30d1fa59caa08d25efb061dccb Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:41:52 -0700 Subject: [PATCH 09/28] Removed DTDL Parser --- core/invehicle-digital-twin/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/invehicle-digital-twin/src/main.rs b/core/invehicle-digital-twin/src/main.rs index 2b8f7eff..7286c649 100644 --- a/core/invehicle-digital-twin/src/main.rs +++ b/core/invehicle-digital-twin/src/main.rs @@ -7,7 +7,7 @@ // Add a new feature to all() so the use statement is active for the feature. // ex. #[cfg(all(feature = "feature_1", feature = "feature_2"))] -#[cfg(any(feature = "managed_subscribe")`)] +#[cfg(any(feature = "managed_subscribe"))] use common::grpc_interceptor::GrpcInterceptorLayer; #[cfg(feature = "managed_subscribe")] From a4b11258d252593aae8bc7c9db9a94567400a1ad Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:45:37 -0700 Subject: [PATCH 10/28] Removed DTDL Parser --- core/invehicle-digital-twin/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/invehicle-digital-twin/src/main.rs b/core/invehicle-digital-twin/src/main.rs index 7286c649..4b299310 100644 --- a/core/invehicle-digital-twin/src/main.rs +++ b/core/invehicle-digital-twin/src/main.rs @@ -7,7 +7,7 @@ // Add a new feature to all() so the use statement is active for the feature. // ex. #[cfg(all(feature = "feature_1", feature = "feature_2"))] -#[cfg(any(feature = "managed_subscribe"))] +#[cfg(feature = "managed_subscribe")] use common::grpc_interceptor::GrpcInterceptorLayer; #[cfg(feature = "managed_subscribe")] From 5c51e0d361e4a6d19a733309ea4253ea42cf4b02 Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:54:45 -0700 Subject: [PATCH 11/28] Removed DTDL Parser --- core/invehicle-digital-twin/src/main.rs | 4 ++-- dtdl-tools/src/dtdl-validator/DtdlValidator.cs | 3 +++ tools/dotnet_append_to_notice.sh | 6 +++++- tools/dotnet_get_licenses.sh | 6 +++++- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/core/invehicle-digital-twin/src/main.rs b/core/invehicle-digital-twin/src/main.rs index 4b299310..c9208bbc 100644 --- a/core/invehicle-digital-twin/src/main.rs +++ b/core/invehicle-digital-twin/src/main.rs @@ -5,8 +5,8 @@ // Module references behind feature flags. Add any necessary module references here. // Start: Module references. -// Add a new feature to all() so the use statement is active for the feature. -// ex. #[cfg(all(feature = "feature_1", feature = "feature_2"))] +// Add a new feature to any() so the use statement is active for the feature. +// ex. #[cfg(any(feature = "feature_1", feature = "feature_2"))] #[cfg(feature = "managed_subscribe")] use common::grpc_interceptor::GrpcInterceptorLayer; diff --git a/dtdl-tools/src/dtdl-validator/DtdlValidator.cs b/dtdl-tools/src/dtdl-validator/DtdlValidator.cs index 87c865cb..9fd4c02b 100644 --- a/dtdl-tools/src/dtdl-validator/DtdlValidator.cs +++ b/dtdl-tools/src/dtdl-validator/DtdlValidator.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// SPDX-License-Identifier: MIT using DTDLParser; using DTDLParser.Models; diff --git a/tools/dotnet_append_to_notice.sh b/tools/dotnet_append_to_notice.sh index fa145723..47c8eaec 100755 --- a/tools/dotnet_append_to_notice.sh +++ b/tools/dotnet_append_to_notice.sh @@ -1,5 +1,9 @@ #!/bin/bash +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT license. +# SPDX-License-Identifier: MIT + set -e # Check if the correct number of arguments are provided @@ -51,4 +55,4 @@ echo -e " This .NET Third Party Licenses list has been generated with [nuget-license](https://github.com/tomchavakis/nuget-license), \ licensed under [Apache License 2.0](https://github.com/tomchavakis/nuget-license/blob/master/LICENSE)" >> "$markdown_file" -exit 0 \ No newline at end of file +exit 0 diff --git a/tools/dotnet_get_licenses.sh b/tools/dotnet_get_licenses.sh index f580156d..b9df1bbb 100755 --- a/tools/dotnet_get_licenses.sh +++ b/tools/dotnet_get_licenses.sh @@ -1,5 +1,9 @@ #!/bin/bash +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT license. +# SPDX-License-Identifier: MIT + set -e # Check if the correct number of arguments are provided @@ -56,4 +60,4 @@ jq -s '.' "$temp_file" > "$json_file" # Remove temporary file rm "$temp_file" -exit 0 \ No newline at end of file +exit 0 From 7e3fe748ce998ebcc9166902b32eb6fd4fa3be93 Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:56:52 -0700 Subject: [PATCH 12/28] Removed DTDL Parser --- digital-twin-model/dtdl/v3/spec/sdv/bad.json | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 digital-twin-model/dtdl/v3/spec/sdv/bad.json diff --git a/digital-twin-model/dtdl/v3/spec/sdv/bad.json b/digital-twin-model/dtdl/v3/spec/sdv/bad.json deleted file mode 100644 index 7701a3a3..00000000 --- a/digital-twin-model/dtdl/v3/spec/sdv/bad.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "@context": ["dtmi:dtdl:context;3"], - "@type": "DeeInterface", - "@id": "dtmi:sdv:OBD;1", - "description": "On-board Diagnostics Interface", - "contents": [ - { - "@type": "Property", - "@id": "dtmi:sdv:OBD:HybridBatteryRemaining;1", - "name": "HybridBatteryRemaining", - "description": "The remaining hybrid battery life.", - "schema": "integer" - } - ] - } -] From 48b7f2b730681eea44df0f1aa0693c35b58b8e2f Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Mon, 9 Oct 2023 13:48:42 -0700 Subject: [PATCH 13/28] Removed DTDL Parser --- README.md | 5 ----- dtdl-tools/README.md | 16 ++++++++++++++++ dtdl-tools/build.rs | 2 +- dtdl-tools/src/lib.rs | 4 ++-- 4 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 dtdl-tools/README.md diff --git a/README.md b/README.md index 0532aa85..81656c9f 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ - [Cloning the Repo](#cloning-the-repo) - [Developer Notes](#developer-notes) - [JSON-LD Crate](#json-ld-crate) - - [DTDL Parser](#dtdl-parser) - [Building](#building) - [Running the Tests](#running-the-tests) - [Running the Samples](#running-the-samples) @@ -96,10 +95,6 @@ However, it currently has a build issue that is discussed [here](https://github. To work around this issue you will need to use git clone to obtain the source from [here](https://github.com/blast-hardcheese/json-ld) and checkout its "resolve-issue-40" branch. It should be cloned to a directory that is a sibling to ibeji. -### DTDL Parser - -There is no existing DTDL Parser for Rust, so we have provided a minimalistic one for DTDL v2 that is based on the [JavaScript DTDL Parser](https://github.com/Azure/azure-sdk-for-js/tree/%40azure/dtdl-parser_1.0.0-beta.2/sdk/digitaltwins/dtdl-parser). - ## Building Once you have installed the prerequisites, go to your enlistment's root directory and run: diff --git a/dtdl-tools/README.md b/dtdl-tools/README.md new file mode 100644 index 00000000..1358f889 --- /dev/null +++ b/dtdl-tools/README.md @@ -0,0 +1,16 @@ +# DTDL Tools + +DTDL is fundamental to Ibeji. These tools will help devleopers to use DTDL to build their own in-vehicle digital twin model. + +## DTDL Validator + +DTDL Validator is an application that validates DTDL files. It uses the .Net DTDLParser. + +The application is built by Cargo. It can be found here: ibeji/target/debug/dtdl-validator/bin/Debug/net7.0/dtdl-validator. +It takes two command line arguments: +* -d - The directory that contains the DTDL files. +* -e - The file extension used by the DTDL files. The default is "json". + +The CI/CD pipeline automatically validates DTDL files found under the ibeji/digital-twin-model/dtdl directory via dtdl-tools +test suite. Additonal directories containing DTDL files can also be checked by addining new test cases based on the one for +the ibeji/digital-twin-model/dtdl directory. diff --git a/dtdl-tools/build.rs b/dtdl-tools/build.rs index 6284fafd..dfeb9fbf 100644 --- a/dtdl-tools/build.rs +++ b/dtdl-tools/build.rs @@ -4,7 +4,7 @@ use std::process::Command; -// This build script builds all the .NET projects in this digital_twins_connector folder. +// This build script builds all the .NET projects in this dtdl-tools folder. // Running 'cargo build' will build the .NET projects and the Rust crates. fn main() { const DOTNET_COMMAND: &str = "dotnet"; diff --git a/dtdl-tools/src/lib.rs b/dtdl-tools/src/lib.rs index da072c14..4410bc6f 100644 --- a/dtdl-tools/src/lib.rs +++ b/dtdl-tools/src/lib.rs @@ -2,10 +2,10 @@ // Licensed under the MIT license. // SPDX-License-Identifier: MIT -// This lib.rs is for running the .NET unit tests in this digital_twins_connector folder. +// This lib.rs is for running the .NET unit tests in this dtdl-tools folder. // Running 'cargo test' will run all the .NET unit tests and the Rust unit tests. #[cfg(test)] -mod digital_twins_connector_dotnet_tests { +mod dtdl_tools_tests { use std::io::{self, Write}; use std::path::Path; use std::process::Command; From 69197190db9a4d64acdc32f3b7adfbc035e6452e Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Tue, 10 Oct 2023 22:35:34 -0700 Subject: [PATCH 14/28] Removed DTDL Parser --- .github/workflows/rust-ci.yml | 1 - core/invehicle-digital-twin/src/main.rs | 8 +++----- .../src/dtdl-validator/Directory.Build.props | 6 +++--- .../src/dtdl-validator/DtdlValidator.cs | 11 +++++----- .../src/dtdl-validator/dtdl-validator.csproj | 20 ++++++++++++++++--- dtdl-tools/src/lib.rs | 12 +++++------ 6 files changed, 33 insertions(+), 25 deletions(-) diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 17a98921..799628e0 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -31,7 +31,6 @@ jobs: - run: cargo clippy --all-targets --all-features --workspace --no-deps -- -D warnings - run: cargo fmt --all -- --check - name: Run doctest only - # we run doctest here as cargo tarpaulin (our test runner) uses: actions-rs/cargo@v1 with: command: test diff --git a/core/invehicle-digital-twin/src/main.rs b/core/invehicle-digital-twin/src/main.rs index c9208bbc..c35aa2bd 100644 --- a/core/invehicle-digital-twin/src/main.rs +++ b/core/invehicle-digital-twin/src/main.rs @@ -5,16 +5,14 @@ // Module references behind feature flags. Add any necessary module references here. // Start: Module references. -// Add a new feature to any() so the use statement is active for the feature. -// ex. #[cfg(any(feature = "feature_1", feature = "feature_2"))] -#[cfg(feature = "managed_subscribe")] -use common::grpc_interceptor::GrpcInterceptorLayer; - #[cfg(feature = "managed_subscribe")] use managed_subscribe::managed_subscribe_module::ManagedSubscribeModule; // End: Module references. +#[allow(unused_imports)] +use common::grpc_interceptor::GrpcInterceptorLayer; + use common::grpc_server::GrpcServer; use core_protobuf_data_access::chariott::service_discovery::core::v1::service_registry_client::ServiceRegistryClient; use core_protobuf_data_access::chariott::service_discovery::core::v1::{ diff --git a/dtdl-tools/src/dtdl-validator/Directory.Build.props b/dtdl-tools/src/dtdl-validator/Directory.Build.props index ba452462..1d9ca1b3 100644 --- a/dtdl-tools/src/dtdl-validator/Directory.Build.props +++ b/dtdl-tools/src/dtdl-validator/Directory.Build.props @@ -1,7 +1,7 @@ - ../../../target/debug/dtdl-validator/bin - ../../../target/debug/dtdl-validator/obj - ../../../target/debug/dtdl-validator/obj + $(OUT_DIR)/dtdl-validator/bin + $(OUT_DIR)/dtdl-validator/obj + $(OUT_DIR)/dtdl-validator/obj diff --git a/dtdl-tools/src/dtdl-validator/DtdlValidator.cs b/dtdl-tools/src/dtdl-validator/DtdlValidator.cs index 9fd4c02b..19f50d4e 100644 --- a/dtdl-tools/src/dtdl-validator/DtdlValidator.cs +++ b/dtdl-tools/src/dtdl-validator/DtdlValidator.cs @@ -79,10 +79,9 @@ static int ValidateDtdl(DirectoryInfo directory, String extension) static async Task Main(string[] args) { - var directoryOption = - new Option( - "-d", - getDefaultValue: () => new DirectoryInfo(Directory.GetCurrentDirectory()), + var directoryArgument = + new Argument( + "directory", description: "The directory that contains the DTDL files."); var extensionOption = new Option( @@ -93,13 +92,13 @@ static async Task Main(string[] args) int exitCode = EXIT_SUCCESS; var cmd = new RootCommand(); - cmd.AddOption(directoryOption); + cmd.AddArgument(directoryArgument); cmd.AddOption(extensionOption); cmd.SetHandler((directory, extension) => { exitCode = ValidateDtdl(directory!, extension!); }, - directoryOption, extensionOption); + directoryArgument, extensionOption); await cmd.InvokeAsync(args); diff --git a/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj b/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj index 240854d5..80177f11 100644 --- a/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj +++ b/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj @@ -1,4 +1,6 @@ + + Exe net7.0 @@ -7,8 +9,20 @@ - - + - + + + + + + + + + + + + + diff --git a/dtdl-tools/src/lib.rs b/dtdl-tools/src/lib.rs index 4410bc6f..a06804e7 100644 --- a/dtdl-tools/src/lib.rs +++ b/dtdl-tools/src/lib.rs @@ -6,16 +6,16 @@ // Running 'cargo test' will run all the .NET unit tests and the Rust unit tests. #[cfg(test)] mod dtdl_tools_tests { + use std::env; use std::io::{self, Write}; use std::path::Path; use std::process::Command; - // The manifest directory is the directory that contains the Cargo.toml file for this crate. - const MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR"); + // The out directory is the directory that contains the build artifacts. + const OUT_DIR: &str = env!("OUT_DIR"); const DTDL_VALIDATOR_FILENAME: &str = "dtdl-validator"; - const DTDL_VALIDATOR_BIN_DIR: &str = "target/debug/dtdl-validator/bin/Debug/net7.0"; - const DTDL_VALIDATOR_DIR_OPTION: &str = "-d"; + const DTDL_VALIDATOR_BIN_DIR: &str = "dtdl-validator/bin/Debug/net7.0"; const DTDL_VALIDATOR_EXT_OPTION: &str = "-e"; /// Validate DTDL files. @@ -24,13 +24,11 @@ mod dtdl_tools_tests { /// * `directory` - The directory that contains the DTDL files that you wish to validate. /// * `extension` - The file extension that the DTDL files use. fn validate_dtdl_files(directory: &str, extension: &str) -> bool { - let dtdl_validator_command_path = Path::new(MANIFEST_DIR) - .join("..") + let dtdl_validator_command_path = Path::new(OUT_DIR) .join(DTDL_VALIDATOR_BIN_DIR) .join(DTDL_VALIDATOR_FILENAME); let dtdl_validator_output = Command::new(dtdl_validator_command_path) - .arg(DTDL_VALIDATOR_DIR_OPTION) .arg(directory) .arg(DTDL_VALIDATOR_EXT_OPTION) .arg(extension) From 2b9236dc85541ac5f76c4a1438d586906ec57c34 Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Wed, 11 Oct 2023 16:30:06 -0700 Subject: [PATCH 15/28] Removed DTDL Parser --- .github/workflows/rust-ci.yml | 8 ++++ dtdl-tools/README.md | 13 ++++-- dtdl-tools/build.rs | 3 ++ dtdl-tools/scripts/install-dtdl-validator.sh | 42 +++++++++++++++++++ .../src/dtdl-validator/dtdl-validator.csproj | 14 ++----- 5 files changed, 66 insertions(+), 14 deletions(-) create mode 100755 dtdl-tools/scripts/install-dtdl-validator.sh diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 799628e0..22e37922 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -21,6 +21,10 @@ jobs: submodules: recursive - name: Install protobuf-compiler run: sudo apt-get install -y protobuf-compiler + - name: Install .NET 7.0 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 7.0 - name: Install stable Rust toolchain run: | rustup show @@ -51,6 +55,10 @@ jobs: submodules: recursive - name: Install protobuf-compiler run: sudo apt-get install -y protobuf-compiler + - name: Install .NET 7.0 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 7.0 - name: Install stable Rust toolchain run: rustup show - name: Cache Dependencies diff --git a/dtdl-tools/README.md b/dtdl-tools/README.md index 1358f889..325d5e38 100644 --- a/dtdl-tools/README.md +++ b/dtdl-tools/README.md @@ -6,11 +6,18 @@ DTDL is fundamental to Ibeji. These tools will help devleopers to use DTDL to bu DTDL Validator is an application that validates DTDL files. It uses the .Net DTDLParser. -The application is built by Cargo. It can be found here: ibeji/target/debug/dtdl-validator/bin/Debug/net7.0/dtdl-validator. +The DTDL Validator application is built by Cargo. It can be found here: ibeji/target/debug/dtdl-validator/bin/Debug/net7.0/dtdl-validator. It takes two command line arguments: -* -d - The directory that contains the DTDL files. -* -e - The file extension used by the DTDL files. The default is "json". + +* -d {directory name} The directory that contains the DTDL files. +* -e {file extension} The file extension used by the DTDL files. The default is "json". The CI/CD pipeline automatically validates DTDL files found under the ibeji/digital-twin-model/dtdl directory via dtdl-tools test suite. Additonal directories containing DTDL files can also be checked by addining new test cases based on the one for the ibeji/digital-twin-model/dtdl directory. + +If you wish to manually run the the DTDL Validator application, then install it from Cargo's out directory to a custom directory by +using the ibeji/dtdl-tools/scripts/install-dtdl-validator.sh script. This script takes two command line arguments: + +* -s {source directory} The Cargo out directory where the application was built. The default is the current directory. +* -d {destination directory} The custom directory where you want the application installed. The default is "$HOME/.cargo/bin/dtdl-validator". diff --git a/dtdl-tools/build.rs b/dtdl-tools/build.rs index dfeb9fbf..db3f02ef 100644 --- a/dtdl-tools/build.rs +++ b/dtdl-tools/build.rs @@ -2,6 +2,7 @@ // Licensed under the MIT license. // SPDX-License-Identifier: MIT +use std::io::{self, Write}; use std::process::Command; // This build script builds all the .NET projects in this dtdl-tools folder. @@ -19,5 +20,7 @@ fn main() { if !output.status.success() { panic!("Failed to run due to {output:?}"); } + + io::stdout().write_all(&output.stdout).unwrap(); } } diff --git a/dtdl-tools/scripts/install-dtdl-validator.sh b/dtdl-tools/scripts/install-dtdl-validator.sh new file mode 100755 index 00000000..d348c6fa --- /dev/null +++ b/dtdl-tools/scripts/install-dtdl-validator.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +set -e + +# Default values +src_dir="." +dst_dir="$HOME/.cargo/bin/dtdl-validator" + +# Parse command line options +while getopts "s:d:" opt; do + case ${opt} in + s) + src_dir="$OPTARG" + ;; + d) + dst_dir="$OPTARG" + ;; + \?) + echo "Invalid option: -$OPTARG" 1>&2 + echo "Usage: $0 [-s source_directory] [-d destination_directory]" 1>&2 + exit 1 + ;; + esac +done + +# Check if dtdl-validator exists in the source directory +if [[ ! -f "$src_dir/dtdl-validator" ]]; then + echo "Error: dtdl-validator must exist in the source directory." 1>&2 + exit 1 +fi + +# Create the destination directory if it does not exist +mkdir -p "$dst_dir" + +# Copy dtdl-validator, its config file and all assocaited dll files to the destination directory +cp "$src_dir/dtdl-validator" "$dst_dir" +cp "$src_dir"/dtdl-validator.runtimeconfig.json "$dst_dir" +cp "$src_dir"/*.dll "$dst_dir" + +echo "dtdl-validator has been successfully installed in $dst_dir" + +exit 0 diff --git a/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj b/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj index 80177f11..534263cd 100644 --- a/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj +++ b/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj @@ -13,16 +13,8 @@ - - - - - - - - - - + + + From a68e5bd5fa2a795d9d911af4afda99061b980d93 Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Wed, 11 Oct 2023 16:39:24 -0700 Subject: [PATCH 16/28] Removed DTDL Parser --- dtdl-tools/src/dtdl-validator/dtdl-validator.csproj | 4 ++-- dtdl-tools/src/lib.rs | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj b/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj index 534263cd..f7aa0b82 100644 --- a/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj +++ b/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj @@ -11,10 +11,10 @@ - + - + diff --git a/dtdl-tools/src/lib.rs b/dtdl-tools/src/lib.rs index a06804e7..d5d6afdb 100644 --- a/dtdl-tools/src/lib.rs +++ b/dtdl-tools/src/lib.rs @@ -24,9 +24,8 @@ mod dtdl_tools_tests { /// * `directory` - The directory that contains the DTDL files that you wish to validate. /// * `extension` - The file extension that the DTDL files use. fn validate_dtdl_files(directory: &str, extension: &str) -> bool { - let dtdl_validator_command_path = Path::new(OUT_DIR) - .join(DTDL_VALIDATOR_BIN_DIR) - .join(DTDL_VALIDATOR_FILENAME); + let dtdl_validator_command_path = + Path::new(OUT_DIR).join(DTDL_VALIDATOR_BIN_DIR).join(DTDL_VALIDATOR_FILENAME); let dtdl_validator_output = Command::new(dtdl_validator_command_path) .arg(directory) From 281816a5aea73cc1b5510025ae3d446c4218f7e5 Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Wed, 11 Oct 2023 21:07:57 -0700 Subject: [PATCH 17/28] Removed DTDL Parser --- dtdl-tools/src/dtdl-validator/dtdl-validator.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj b/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj index f7aa0b82..def6b7df 100644 --- a/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj +++ b/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj @@ -4,6 +4,7 @@ Exe net7.0 + /tmp From b97f1b9f2f00a20d2b617508c12fa66e57e00c2e Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Thu, 12 Oct 2023 09:26:00 -0700 Subject: [PATCH 18/28] Removed DTDL Parser --- dtdl-tools/build.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dtdl-tools/build.rs b/dtdl-tools/build.rs index db3f02ef..66ff3307 100644 --- a/dtdl-tools/build.rs +++ b/dtdl-tools/build.rs @@ -2,6 +2,7 @@ // Licensed under the MIT license. // SPDX-License-Identifier: MIT +use std::env; use std::io::{self, Write}; use std::process::Command; @@ -10,8 +11,8 @@ use std::process::Command; fn main() { const DOTNET_COMMAND: &str = "dotnet"; const DOTNET_BUILD_ARG: &str = "build"; - const CSPROJ_PATHS: &[&str] = &["src/dtdl-validator/dtdl-validator.csproj"]; + const CARGO_MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR"); for csproj in CSPROJ_PATHS { let output = @@ -23,4 +24,6 @@ fn main() { io::stdout().write_all(&output.stdout).unwrap(); } + + println!("cargo:rerun-if-changed={CARGO_MANIFEST_DIR}/src/dtdl-validator"); } From 0a9afdbee3a970f50925bf19946079cb24df6112 Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Thu, 12 Oct 2023 20:59:59 -0700 Subject: [PATCH 19/28] Removed DTDL Parser --- dtdl-tools/src/dtdl-validator/Directory.Build.props | 6 +++--- dtdl-tools/src/dtdl-validator/dtdl-validator.csproj | 1 - dtdl-tools/src/lib.rs | 4 +++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/dtdl-tools/src/dtdl-validator/Directory.Build.props b/dtdl-tools/src/dtdl-validator/Directory.Build.props index 1d9ca1b3..da01ed10 100644 --- a/dtdl-tools/src/dtdl-validator/Directory.Build.props +++ b/dtdl-tools/src/dtdl-validator/Directory.Build.props @@ -1,7 +1,7 @@ - $(OUT_DIR)/dtdl-validator/bin - $(OUT_DIR)/dtdl-validator/obj - $(OUT_DIR)/dtdl-validator/obj + $(OUT_DIR)/$(BaseOutputPath) + $(OUT_DIR)/$(BaseIntermediateOutputPath) + diff --git a/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj b/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj index def6b7df..f7aa0b82 100644 --- a/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj +++ b/dtdl-tools/src/dtdl-validator/dtdl-validator.csproj @@ -4,7 +4,6 @@ Exe net7.0 - /tmp diff --git a/dtdl-tools/src/lib.rs b/dtdl-tools/src/lib.rs index d5d6afdb..3e1d2b90 100644 --- a/dtdl-tools/src/lib.rs +++ b/dtdl-tools/src/lib.rs @@ -15,7 +15,7 @@ mod dtdl_tools_tests { const OUT_DIR: &str = env!("OUT_DIR"); const DTDL_VALIDATOR_FILENAME: &str = "dtdl-validator"; - const DTDL_VALIDATOR_BIN_DIR: &str = "dtdl-validator/bin/Debug/net7.0"; + const DTDL_VALIDATOR_BIN_DIR: &str = "Debug/net7.0"; const DTDL_VALIDATOR_EXT_OPTION: &str = "-e"; /// Validate DTDL files. @@ -27,6 +27,8 @@ mod dtdl_tools_tests { let dtdl_validator_command_path = Path::new(OUT_DIR).join(DTDL_VALIDATOR_BIN_DIR).join(DTDL_VALIDATOR_FILENAME); + println!("dtdl_validator_command_path = '{:?}", dtdl_validator_command_path); + let dtdl_validator_output = Command::new(dtdl_validator_command_path) .arg(directory) .arg(DTDL_VALIDATOR_EXT_OPTION) From f5b7c721f262c0367bc5c7a51f6828804bca8a5f Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Thu, 12 Oct 2023 21:06:17 -0700 Subject: [PATCH 20/28] Removed DTDL Parser --- dtdl-tools/src/dtdl-validator/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtdl-tools/src/dtdl-validator/Directory.Build.props b/dtdl-tools/src/dtdl-validator/Directory.Build.props index da01ed10..61c042ec 100644 --- a/dtdl-tools/src/dtdl-validator/Directory.Build.props +++ b/dtdl-tools/src/dtdl-validator/Directory.Build.props @@ -2,6 +2,6 @@ $(OUT_DIR)/$(BaseOutputPath) $(OUT_DIR)/$(BaseIntermediateOutputPath) - + $(OUT_DIR)/$(MSBuildProjectExtensionsPath) From ed1702f6f4abbe4d9fbc5d37ddc30e559ce5e1e7 Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Thu, 12 Oct 2023 21:15:42 -0700 Subject: [PATCH 21/28] Removed DTDL Parser --- dtdl-tools/src/dtdl-validator/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtdl-tools/src/dtdl-validator/Directory.Build.props b/dtdl-tools/src/dtdl-validator/Directory.Build.props index 61c042ec..2907253a 100644 --- a/dtdl-tools/src/dtdl-validator/Directory.Build.props +++ b/dtdl-tools/src/dtdl-validator/Directory.Build.props @@ -2,6 +2,6 @@ $(OUT_DIR)/$(BaseOutputPath) $(OUT_DIR)/$(BaseIntermediateOutputPath) - $(OUT_DIR)/$(MSBuildProjectExtensionsPath) + From 6e6a10647ce1964e1f1cea792be2a0d9826e114c Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Thu, 12 Oct 2023 21:37:58 -0700 Subject: [PATCH 22/28] Removed DTDL Parser --- dtdl-tools/src/dtdl-validator/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtdl-tools/src/dtdl-validator/Directory.Build.props b/dtdl-tools/src/dtdl-validator/Directory.Build.props index 2907253a..4b0e50fc 100644 --- a/dtdl-tools/src/dtdl-validator/Directory.Build.props +++ b/dtdl-tools/src/dtdl-validator/Directory.Build.props @@ -1,7 +1,7 @@ + $(OUT_DIR)/$(BaseOutputPath) $(OUT_DIR)/$(BaseIntermediateOutputPath) - From 778d5ba33ff11f486304ab1767b2bbb67f5523fb Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Thu, 12 Oct 2023 22:27:55 -0700 Subject: [PATCH 23/28] Removed DTDL Parser --- .../actions/install-rust-toolchain/action.yml | 23 +++++++++++++++++++ .github/workflows/notice-generation.yml | 4 ++-- .github/workflows/rust-ci.yml | 12 +++++----- 3 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/actions/install-rust-toolchain/action.yml diff --git a/.github/workflows/actions/install-rust-toolchain/action.yml b/.github/workflows/actions/install-rust-toolchain/action.yml new file mode 100644 index 00000000..d6da2ffc --- /dev/null +++ b/.github/workflows/actions/install-rust-toolchain/action.yml @@ -0,0 +1,23 @@ +name: Install Rust Toolchain +description: | + Installs the rust toolchain. + Relies on the fact that rustup show will install a toolchain. The installed version is based on a toolchain file, or stable if no such file is found. +inputs: + components: + description: A list of additional components to install + required: false + default: null +runs: + using: "composite" + steps: + - name: Install Rust Toolchain + # A note on using rustup show to do this (from https://rust-lang.github.io/rustup/overrides.html): + # To verify which toolchain is active, you can use rustup show, + # which will also try to install the corresponding toolchain if the current one has not been installed [...]. + # (Please note that this behavior is subject to change, as detailed in issue #1397 [https://github.com/rust-lang/rustup/issues/1397].) + run: rustup show + shell: bash + - name: Install Additional Components + run: rustup component add ${{ inputs.components }} + shell: bash + if: ${{ inputs.components != null }} \ No newline at end of file diff --git a/.github/workflows/notice-generation.yml b/.github/workflows/notice-generation.yml index e53183ab..ac1813d8 100644 --- a/.github/workflows/notice-generation.yml +++ b/.github/workflows/notice-generation.yml @@ -16,8 +16,8 @@ jobs: uses: actions/checkout@v3 with: submodules: recursive - - name: Install stable toolchain - run: rustup show + - name: Install toolchain + uses: ./.github/actions/install-rust-toolchain - name: Cache Dependencies uses: Swatinem/rust-cache@v1 - name: Generate the Notice diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 22e37922..6e7ea40e 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -25,10 +25,10 @@ jobs: uses: actions/setup-dotnet@v3 with: dotnet-version: 7.0 - - name: Install stable Rust toolchain - run: | - rustup show - rustup component add rustfmt clippy + - name: Install Rust toolchain + uses: ./.github/actions/install-rust-toolchain + with: + components: clippy rustfmt - name: Cache Dependencies uses: Swatinem/rust-cache@v2 - run: cargo check --workspace @@ -59,8 +59,8 @@ jobs: uses: actions/setup-dotnet@v3 with: dotnet-version: 7.0 - - name: Install stable Rust toolchain - run: rustup show + - name: Install Rust toolchain + uses: ./.github/actions/install-rust-toolchain - name: Cache Dependencies uses: Swatinem/rust-cache@v2 - name: Build From 7ccd4a37aea1c80af42280ab2bc9a4efa420e16e Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Thu, 12 Oct 2023 22:36:38 -0700 Subject: [PATCH 24/28] Removed DTDL Parser --- .github/{workflows => }/actions/install-rust-toolchain/action.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{workflows => }/actions/install-rust-toolchain/action.yml (100%) diff --git a/.github/workflows/actions/install-rust-toolchain/action.yml b/.github/actions/install-rust-toolchain/action.yml similarity index 100% rename from .github/workflows/actions/install-rust-toolchain/action.yml rename to .github/actions/install-rust-toolchain/action.yml From 3a372948243c7d65a1acbe738bbf81396324fad9 Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Fri, 13 Oct 2023 10:37:18 -0700 Subject: [PATCH 25/28] Removed DTDL Parser --- dtdl-tools/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dtdl-tools/README.md b/dtdl-tools/README.md index 325d5e38..9308a012 100644 --- a/dtdl-tools/README.md +++ b/dtdl-tools/README.md @@ -1,10 +1,10 @@ # DTDL Tools -DTDL is fundamental to Ibeji. These tools will help devleopers to use DTDL to build their own in-vehicle digital twin model. +DTDL is fundamental to Ibeji. These tools will help developers to use DTDL to build their own in-vehicle digital twin model. ## DTDL Validator -DTDL Validator is an application that validates DTDL files. It uses the .Net DTDLParser. +DTDL Validator is an application that validates DTDL files. It uses the .NET DTDLParser. The DTDL Validator application is built by Cargo. It can be found here: ibeji/target/debug/dtdl-validator/bin/Debug/net7.0/dtdl-validator. It takes two command line arguments: From 026fa35fbecb90ccbf38ccaabae5863386b438c8 Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Fri, 13 Oct 2023 10:40:19 -0700 Subject: [PATCH 26/28] Removed DTDL Parser --- .github/actions/install-rust-toolchain/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/install-rust-toolchain/action.yml b/.github/actions/install-rust-toolchain/action.yml index d6da2ffc..b89712a6 100644 --- a/.github/actions/install-rust-toolchain/action.yml +++ b/.github/actions/install-rust-toolchain/action.yml @@ -1,6 +1,6 @@ name: Install Rust Toolchain description: | - Installs the rust toolchain. + Installs the Rust toolchain. Relies on the fact that rustup show will install a toolchain. The installed version is based on a toolchain file, or stable if no such file is found. inputs: components: From 51e706cd8d7a95865511f69f2c18874cd366c126 Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Tue, 17 Oct 2023 12:39:59 -0700 Subject: [PATCH 27/28] Removed DTDL Parser --- dtdl-tools/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtdl-tools/README.md b/dtdl-tools/README.md index 9308a012..367aafde 100644 --- a/dtdl-tools/README.md +++ b/dtdl-tools/README.md @@ -4,7 +4,7 @@ DTDL is fundamental to Ibeji. These tools will help developers to use DTDL to bu ## DTDL Validator -DTDL Validator is an application that validates DTDL files. It uses the .NET DTDLParser. +The DTDL Validator is an application that validates DTDL files. It uses the .NET DTDLParser. The DTDL Validator application is built by Cargo. It can be found here: ibeji/target/debug/dtdl-validator/bin/Debug/net7.0/dtdl-validator. It takes two command line arguments: From 2d2b4d807537b18820d819c44355408a772ee8bf Mon Sep 17 00:00:00 2001 From: Ash Beitz <8304894+ashbeitz@users.noreply.github.com> Date: Tue, 17 Oct 2023 13:12:27 -0700 Subject: [PATCH 28/28] Removed DTDL Parser --- dtdl-tools/scripts/install-dtdl-validator.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dtdl-tools/scripts/install-dtdl-validator.sh b/dtdl-tools/scripts/install-dtdl-validator.sh index d348c6fa..8d622e4c 100755 --- a/dtdl-tools/scripts/install-dtdl-validator.sh +++ b/dtdl-tools/scripts/install-dtdl-validator.sh @@ -1,5 +1,9 @@ #!/bin/bash +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT license. +# SPDX-License-Identifier: MIT + set -e # Default values