diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..03f4879 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +rustflags = ["-Ctarget-cpu=native"] diff --git a/.gitignore b/.gitignore index 1fcceda..a6a75d4 100644 --- a/.gitignore +++ b/.gitignore @@ -17,5 +17,15 @@ __pycache__/ build/ dist/ logs/ -master_mapping.rs + +# protobuf +mod.rs +command_data.rs +serverdata.rs + +# cangen files generaed by calypsogen.py +decode_master_mapping.rs decode_data.rs +encode_data.rs +encode_master_mapping.rs +format_data.rs diff --git a/Cargo.lock b/Cargo.lock index 17697f7..ec8ed37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,9 +48,9 @@ checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "bitstream-io" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c12d1856e42f0d817a835fe55853957c85c8c8a470114029143d3f12671446e" +checksum = "3dcde5f311c85b8ca30c2e4198d4326bc342c76541590106f5fa4a50946ea499" [[package]] name = "byte_conv" diff --git a/Cargo.toml b/Cargo.toml index 932ac79..c40490f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ name = "calypso" version = "0.1.0" edition = "2021" +rust-version = "1.79" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -10,4 +11,13 @@ socketcan = "3.3.0" paho-mqtt = "0.12.5" protobuf-codegen = "3.3.0" protobuf = "3.3.0" -bitstream-io = "2.3.0" +bitstream-io = "2.5.0" + + +[build-dependencies] +protobuf-codegen = "3.3.0" + +[profile.release] +lto = true +codegen-units = 1 +panic = "abort" diff --git a/Embedded-Base b/Embedded-Base index fee72b6..fdfdca7 160000 --- a/Embedded-Base +++ b/Embedded-Base @@ -1 +1 @@ -Subproject commit fee72b67f774d9437123e85c9399f33a998bb4a4 +Subproject commit fdfdca783209c293807b1e71efc5447d754050eb diff --git a/build.rs b/build.rs index 4d1ed5d..dfc6bb2 100644 --- a/build.rs +++ b/build.rs @@ -17,4 +17,15 @@ fn main() { std::process::exit(1); } } + + protobuf_codegen::Codegen::new() + .pure() + // All inputs and imports from the inputs must reside in `includes` directories. + .includes(["src/proto"]) + // Inputs must reside in some of include paths. + .input("src/proto/command_data.proto") + .input("src/proto/serverdata.proto") + // Specify output directory relative to Cargo output directory. + .out_dir("src") + .run_from_script(); } diff --git a/calypsogen.py b/calypsogen.py index ab24e1d..4f883d5 100644 --- a/calypsogen.py +++ b/calypsogen.py @@ -17,24 +17,44 @@ spec.loader.exec_module(cangen) decode_data = open("./src/decode_data.rs", "w") -master_mapping = open("./src/master_mapping.rs", "w") +decode_master_mapping = open("./src/decode_master_mapping.rs", "w") + +encode_data = open("./src/encode_data.rs", "w") +encode_master_mapping = open("./src/encode_master_mapping.rs", "w") + +format_data = open("./src/format_data.rs", "w") + bms_messages = cangen.YAMLParser().parse(open(f"{EMBEDDED_BASE_PATH}/{module_name}/can-messages/bms.yaml", "r")) mpu_messages = cangen.YAMLParser().parse(open(f"{EMBEDDED_BASE_PATH}/{module_name}/can-messages/mpu.yaml", "r")) wheel_messages = cangen.YAMLParser().parse(open(f"{EMBEDDED_BASE_PATH}/{module_name}/can-messages/wheel.yaml", "r")) dti_messages = cangen.YAMLParser().parse(open(f"{EMBEDDED_BASE_PATH}/{module_name}/can-messages/dti.yaml", "r")) +calypso_messages = cangen.YAMLParser().parse(open(f"{EMBEDDED_BASE_PATH}/{module_name}/can-messages/calypso_cmd.yaml", "r")) charger_messages = cangen.YAMLParser().parse(open(f"{EMBEDDED_BASE_PATH}/{module_name}/can-messages/charger.yaml", "r")) +msb_messages = cangen.YAMLParser().parse(open(f"{EMBEDDED_BASE_PATH}/{module_name}/can-messages/msb.yaml", "r")) bms_messages.msgs.extend(mpu_messages.msgs) bms_messages.msgs.extend(wheel_messages.msgs) bms_messages.msgs.extend(dti_messages.msgs) bms_messages.msgs.extend(charger_messages.msgs) +bms_messages.msgs.extend(calypso_messages.msgs) +bms_messages.msgs.extend(msb_messages.msgs) result = cangen.RustSynth().parse_messages(bms_messages.msgs) decode_data.write(result.decode_data) decode_data.close() -master_mapping.write(result.master_mapping) -master_mapping.close() +decode_master_mapping.write(result.decode_master_mapping) +decode_master_mapping.close() + +encode_data.write(result.encode_data) +encode_data.close() + +encode_master_mapping.write(result.encode_master_mapping) +encode_master_mapping.close() + +format_data.write(result.format_data) +format_data.close() + diff --git a/src/data.rs b/src/data.rs index e797ead..34fc8aa 100644 --- a/src/data.rs +++ b/src/data.rs @@ -3,7 +3,7 @@ use std::fmt; /** * Wrapper Class for Data coming off the car */ -pub struct Data { +pub struct DecodeData { pub value: Vec, pub topic: String, pub unit: String, @@ -12,7 +12,7 @@ pub struct Data { /** * Implementation for the format of the data for debugging purposes */ -impl fmt::Display for Data { +impl fmt::Display for DecodeData { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Overrides the string representation of the class. @@ -25,9 +25,9 @@ impl fmt::Display for Data { } /** - * Implementation fo the Data Structs' methods + * Implementation fo the DecodeData methods */ -impl Data { +impl DecodeData { /** * Constructor * @param id: the id of the data @@ -42,3 +42,42 @@ impl Data { } } } + +/** + * Wrapper Class for data going into the car + */ +pub struct EncodeData { + pub value: Vec, + pub id: u32, + pub is_ext: bool, +} + +/** + * Implementation for the format of the data for debugging purposes + */ +impl fmt::Display for EncodeData { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Overrides the string representation of the class. + + write!( + f, + "{}#{:?} (extended: {})", + self.id, self.value, self.is_ext + ) + } +} + +/** + * Implementation fo the DecodeData methods + */ +impl EncodeData { + /** + * Constructor + * @param id: the id of the can message + * @param value: the can message payload + * @param is_ext: whether the can message is extended format ID + */ + pub fn new(id: u32, value: Vec, is_ext: bool) -> Self { + Self { id, value, is_ext } + } +} diff --git a/src/message.rs b/src/decodable_message.rs similarity index 71% rename from src/message.rs rename to src/decodable_message.rs index 2783ed8..9d1304e 100644 --- a/src/message.rs +++ b/src/decodable_message.rs @@ -1,10 +1,10 @@ -use super::data::Data; +use super::data::DecodeData; -use super::master_mapping::get_message_info; +use super::decode_master_mapping::get_message_info; /** * Wrapper class for an individual message. */ -pub struct Message { +pub struct DecodableMessage { id: u32, data: Vec, } @@ -12,7 +12,7 @@ pub struct Message { /** * Implementation of Message. */ -impl Message { +impl DecodableMessage { /** * Creates a new message with the given timestamp, id, and data. */ @@ -23,8 +23,8 @@ impl Message { /** * Decodes the message and returns a vector of Data objects. */ - pub fn decode(&self) -> Vec { - Message::decode_message(&self.id, &self.data) + pub fn decode(&self) -> Vec { + DecodableMessage::decode_message(&self.id, &self.data) } /** @@ -35,9 +35,9 @@ impl Message { * param data: The data of the message. * return: A vector of Data objects. */ - fn decode_message(id: &u32, data: &[u8]) -> Vec { + fn decode_message(id: &u32, data: &[u8]) -> Vec { let decoder = get_message_info(id).decoder; - let mut decoded_data: Vec = Vec::new(); + let mut decoded_data: Vec = Vec::new(); let result = decoder(data); for data in result { decoded_data.push(data); diff --git a/src/encodable_message.rs b/src/encodable_message.rs new file mode 100644 index 0000000..d8d3775 --- /dev/null +++ b/src/encodable_message.rs @@ -0,0 +1,41 @@ +use crate::data::EncodeData; + +use super::encode_master_mapping::get_message_info; +/** + * Wrapper class for an individual encodable message. + */ +pub struct EncodableMessage { + key: String, + data: Vec, +} + +/** + * Implementation of Message. + */ +impl EncodableMessage { + /** + * Creates a new message with the given string key and value + */ + pub fn new(key: String, data: Vec) -> Self { + Self { key, data } + } + + /** + * Decodes the message and returns a struct which defines a CAN packet + */ + pub fn encode(self) -> EncodeData { + EncodableMessage::encode_message(self.key, self.data) + } + + /** + * Decodes the message and returns a vector of Data objects. + * Achieves this by calling the decoder function associated with the message key. + * param key: The key of the message. + * param data: The data of the message. + * return: A vector of Data objects. + */ + fn encode_message(key: String, data: Vec) -> EncodeData { + let encoder = get_message_info(key).encoder; + encoder(data) + } +} diff --git a/src/lib.rs b/src/lib.rs index d45c958..46b7483 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,11 @@ +pub mod command_data; pub mod data; +pub mod decodable_message; pub mod decode_data; -pub mod master_mapping; -pub mod message; +pub mod decode_master_mapping; +pub mod encodable_message; +pub mod encode_data; +pub mod encode_master_mapping; +pub mod format_data; pub mod mqtt; pub mod serverdata; diff --git a/src/main.rs b/src/main.rs index a62de0d..b4e3f1c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,22 +1,31 @@ -use std::{env, process}; +use std::{ + collections::HashMap, + env, process, + sync::{Arc, RwLock}, + thread::{self, JoinHandle}, + time::Duration, +}; -use calypso::{message::Message, mqtt::MqttClient}; -use socketcan::{CanFrame, CanSocket, EmbeddedFrame, Socket}; +use calypso::{ + command_data, data::EncodeData, decodable_message::DecodableMessage, + encodable_message::EncodableMessage, encode_master_mapping::ENCODABLE_KEY_LIST, + mqtt::MqttClient, serverdata, +}; +use protobuf::Message; +use socketcan::{CanFrame, CanSocket, EmbeddedFrame, Id, Socket}; + +const ENCODER_MAP_SUB: &str = "Calypso/Bidir/Command/#"; /** * Reads the can socket and publishes the data to the given client. */ -fn read_can(mut publisher: MqttClient, can_interface: &str) { +fn read_can(pub_path: &str, can_interface: &str) -> JoinHandle { //open can socket channel at name can_interface - let socket = CanSocket::open(can_interface); - let socket = match socket { - Ok(socket) => socket, - Err(err) => { - println!("Failed to open CAN socket: {}", err); - return; - } - }; - loop { + let mut client = MqttClient::new(pub_path, "calypso-decoder"); + client.connect().expect("Could not connect to Siren!"); + let socket = CanSocket::open(can_interface).expect("Failed to open CAN socket!"); + + thread::spawn(move || loop { let msg = match socket.read_frame() { Ok(CanFrame::Data(msg)) => msg, Ok(CanFrame::Remote(_)) => { @@ -33,7 +42,7 @@ fn read_can(mut publisher: MqttClient, can_interface: &str) { } }; let data = msg.data(); - let message = Message::new( + let message = DecodableMessage::new( match msg.id() { socketcan::Id::Standard(std) => std.as_raw().into(), socketcan::Id::Extended(ext) => ext.as_raw(), @@ -42,15 +51,132 @@ fn read_can(mut publisher: MqttClient, can_interface: &str) { ); let decoded_data = message.decode(); for data in decoded_data.iter() { - publisher.publish(data) + let mut payload = serverdata::ServerData::new(); + payload.unit = data.unit.to_string(); + payload.value = data.value.iter().map(|x| x.to_string()).collect(); + + client + .publish( + data.topic.to_string(), + protobuf::Message::write_to_bytes(&payload).unwrap_or_else(|e| { + format!("failed to serialize {}", e).as_bytes().to_vec() + }), + ) + .expect("Could not publish!"); + // TODO: investigate disabling this + thread::sleep(Duration::from_micros(100)); } + }) +} + +/** + * Reads the mqtt incoming messages and sends can messages based off of that + */ +fn read_siren(pub_path: &str, send_map: Arc>>) -> JoinHandle<()> { + let mut client = MqttClient::new(pub_path, "calypso-encoder"); + client.connect().expect("Could not connect to Siren!"); + let reciever = client.start_consumer().expect("Could not begin consuming"); + client + .subscribe(ENCODER_MAP_SUB) + .expect("Could not subscribe!"); + + // do the default initialization for all, do outside of the thread to save time negotiating when send_can comes up + let mut writable_send_map = send_map.write().expect("Could not modify send messages!"); + for key in ENCODABLE_KEY_LIST { + let packet = EncodableMessage::new(String::clone(&key.to_owned()), Vec::new()); + let ret = packet.encode(); + writable_send_map.insert(ret.id, ret); } + drop(writable_send_map); + + thread::spawn(move || { + for msg in reciever.iter() { + if let Some(msg) = msg { + let buf = match command_data::CommandData::parse_from_bytes(msg.payload()) { + Ok(buf) => buf, + Err(err) => { + println!("Could not decode command: {}", err); + continue; + } + }; + let key = match msg.topic().split('/').last() { + Some(key) => key.to_owned(), + None => { + println!("Could not parse the key value in {}", msg.topic()); + continue; + } + }; + + let packet = EncodableMessage::new(String::clone(&key), buf.data); + let ret = packet.encode(); + send_map + .write() + .expect("Could not modify send messages!") + .insert(ret.id, ret); + } else { + // the code doesnt work without this else statement + // idk why but never remove this else statement + let is_conn = client.is_connected(); + println!("Client is {}", is_conn); + if !is_conn { + println!("Trying to reconnect"); + match client.reconnect() { + Ok(_) => println!("Reconnected!"), + Err(_) => println!("Could not reconnect!"), + } + continue; + } + } + } + }) +} + +fn send_out( + can_interface: &str, + send_map: Arc>>, +) -> JoinHandle<()> { + let socket = CanSocket::open(can_interface).expect("Failed to open CAN socket!"); + + thread::spawn(move || loop { + thread::sleep(Duration::from_millis(750)); + let sender = send_map.read().expect("Cannot read map of sendables!"); + for msg in sender.iter() { + // let id = u32::from_str_radix((msg.1.1).trim_start_matches("0x"), 16).expect("Invalid CAN ID!"); + + let id: Id = if !msg.1.is_ext { + socketcan::StandardId::new( + msg.1 + .id + .try_into() + .unwrap_or_else(|_| panic!("Invalid standard ID: {}", msg.1.id)), + ) + .unwrap_or_else(|| panic!("Invalid standard ID: {}", msg.1.id)) + .into() + } else { + socketcan::ExtendedId::new(msg.1.id) + .unwrap_or_else(|| panic!("Invalid extended ID: {}", msg.1.id)) + .into() + }; + + match CanFrame::new(id, &msg.1.value) { + Some(packet) => { + match socket.write_frame(&packet) { + Ok(_) => (), + Err(err) => println!("Error sending can message {}", err), + }; + } + None => { + println!("Packet is too long: {}", msg.1); + } + } + } + }) } /** * Parses the command line arguments. */ -fn parse_args() -> (String, String) { +fn parse_args() -> (String, String, bool) { let args: Vec = env::args().collect(); println!("{:?}", args); if args.len() < 3 { @@ -60,25 +186,43 @@ fn parse_args() -> (String, String) { } let path = &args[1]; let can_interface = &args[2]; + let encode_en = args.len() >= 4 && args[3] == "encode_en"; println!("Siren URL: {}", path); println!("Can interface: {}", can_interface); - (String::from(path), String::from(can_interface)) + (String::from(path), String::from(can_interface), encode_en) } /** * Main Function * Configures the can network, retrieves the client based on the command line arguments, * connects the client and then reads the can socket from specified interface. - * Sample Call for Mqtt "/home/ner/Desktop/Calypso/target/release/calypso mqtt localhost:1883 &" * - * 3rd argument: if a can interface is passed the program will use it instead of the default can0 - * Ex: "/home/ner/Desktop/Calypso/target/release/calypso mqtt localhost:1883 can0 &" + * Args: + * 1 -> IP address:port of Siren mqtt server (ex. localhost:1883) + * 2 -> Socketcan interface name (ex. vcan0) + * 3 -> encode_en or blank, whether to enable encoding */ fn main() { - let (path, can_interface) = parse_args(); - let mut client = MqttClient::new(); - client.connect(&path); - read_can(client, &can_interface); + let (path, can_interface, encoding) = parse_args(); + let can_handle = read_can(&path, &can_interface); + + // use a arc for mutlithread, and a rwlock to enforce one writer + if encoding { + let send_map: Arc>> = Arc::new(RwLock::new(HashMap::new())); + + let siren_handle = read_siren(&path, Arc::clone(&send_map)); + + let send_handle = send_out(&can_interface, Arc::clone(&send_map)); + + siren_handle.join().expect("Encoder failed with "); + println!("Encoder ended"); + + send_handle.join().expect("Sender failed with "); + println!("Sender ended"); + } + + can_handle.join().expect("Decoder failed with "); + println!("Decoder ended"); } diff --git a/src/mqtt.rs b/src/mqtt.rs index 48dae0e..cbde325 100644 --- a/src/mqtt.rs +++ b/src/mqtt.rs @@ -1,27 +1,13 @@ extern crate paho_mqtt as mqtt; use mqtt::ServerResponse; +use paho_mqtt::{Message, Receiver}; use std::time::Duration; -use std::{process, thread}; - -use crate::data::Data; -use crate::serverdata; - -const DFLT_CLIENT: &str = "calypso"; /** * MqttClient is a wrapper around the paho_mqtt::Client. */ pub struct MqttClient { - client: Option, -} - -impl Default for MqttClient { - /** - * Creates a new MqttClient. - */ - fn default() -> Self { - Self::new() - } + client: mqtt::Client, } /** @@ -31,115 +17,88 @@ impl MqttClient { /** * Creates a new MqttClient. */ - pub fn new() -> MqttClient { - MqttClient { client: None } + pub fn new(host_name: &str, client_id: &str) -> Self { + let create_options = mqtt::CreateOptionsBuilder::new() + .server_uri(host_name) + .client_id(client_id) + .finalize(); + MqttClient { + client: mqtt::Client::new(create_options).expect("Could not instantiate MQTT client"), + } } - - pub fn connect(&mut self, host: &str) { - self._set_host(&host.to_string()); - self._connect(); + /** + * Sets the hostname and connects to the server + */ + pub fn connect(&mut self) -> Result { + self._connect() } - pub fn publish(&mut self, data: &Data) { - let topic = data.topic.to_string(); - let mut payload = serverdata::ServerData::new(); - payload.unit = data.unit.to_string(); - payload.value = data.value.iter().map(|x| x.to_string()).collect(); + /**const DFLT_CLIENT: &str = "calypso"; - /* If the client is initialized, publish the data. */ - if let Some(client) = &self.client { - let msg = mqtt::MessageBuilder::new() - .topic(topic) - .payload( - protobuf::Message::write_to_bytes(&payload) - .unwrap_or("failed to serialize".as_bytes().to_vec()), - ) - .finalize(); - - match client.publish(msg) { - Ok(_) => (), - Err(e) => println!("Error sending message: {:?}", e), - } - thread::sleep(Duration::from_micros(100)); - } else { - println!("Client not initialized, please set host first and connect") - } + * Publishes a protobuf packet to the server + */ + pub fn publish(&mut self, topic: String, payload: Vec) -> Result<(), mqtt::errors::Error> { + let msg = mqtt::MessageBuilder::new() + .topic(topic) + .payload(payload) + .finalize(); + self.client.publish(msg) } - fn _set_host(&mut self, host_name: &String) { - let create_options = mqtt::CreateOptionsBuilder::new() - .server_uri(host_name) - .client_id(DFLT_CLIENT.to_string()) - .finalize(); - self.client = Some(match mqtt::Client::new(create_options) { - Ok(client) => client, - Err(e) => { - println!("Error creating the client: {:?}", e); - process::exit(1); - } - }); + /** + * Starts the client consuming messages. + * This starts the client receiving messages and placing them into an mpsc queue. + * It returns the receiving-end of the queue for the application to get the messages. + * This can be called at any time after the client is created, but it should be called before subscribing to any topics, otherwise messages can be lost. + */ + pub fn start_consumer(&mut self) -> Option>> { + Some(self.client.start_consuming()) } + /** + * Subscribes to a single topic. + * topic: the topic to be subscribed to + */ + pub fn subscribe(&mut self, topic: &str) -> Result { + self.client.subscribe(topic, 2) + } /** * Connects to the broker. * Sets the last will and testament. */ - fn _connect(&mut self) { - if let Some(client) = &self.client { - let lastwilltestatment = mqtt::MessageBuilder::new() - .topic("Calypso/Status") - .payload("Calypso is offline") - .finalize(); - let conn_opts = mqtt::ConnectOptionsBuilder::new() - .keep_alive_interval(Duration::from_secs(20)) - .clean_session(false) - .will_message(lastwilltestatment) - .automatic_reconnect(Duration::from_secs(1), Duration::from_secs(30)) - .finalize(); - if let Err(e) = client.connect(conn_opts) { - println!("Unable to connect:\n\t{:?}", e); - } - } else { - println!("Client not initialized, please set host first"); - } + fn _connect(&mut self) -> Result { + let lastwilltestatment = mqtt::MessageBuilder::new() + .topic("Calypso/Status") + .payload(format!("Calypso {} is offline", self.client.client_id())) + .finalize(); + let conn_opts = mqtt::ConnectOptionsBuilder::new_v5() + .keep_alive_interval(Duration::from_secs(20)) + .clean_session(false) + .will_message(lastwilltestatment) + .automatic_reconnect(Duration::from_secs(1), Duration::from_secs(30)) + .finalize(); + self.client.connect(conn_opts) } /** * Check if the client is connected to the broker. */ - fn _is_connected(&self) -> bool { - if let Some(client) = &self.client { - client.is_connected() - } else { - println!("Client not initialized, please set host first"); - false - } + pub fn is_connected(&self) -> bool { + self.client.is_connected() } /** * Reconnect to the broker. */ - fn _reconnect(&mut self) -> Result { - if let Some(client) = &self.client { - client.reconnect() - } else { - Err(mqtt::Error::General( - "Client not initialized, please set host first", - )) - } + pub fn reconnect(&mut self) -> Result { + self.client.reconnect() } /** * Disconnect from the broker. */ fn _disconnect(&mut self) -> Result<(), mqtt::Error> { - if let Some(client) = &self.client { - client.disconnect(None) - } else { - Err(mqtt::Error::General( - "Client not initialized, please set host first", - )) - } + self.client.disconnect(None) } } diff --git a/src/proto/command_data.proto b/src/proto/command_data.proto new file mode 100644 index 0000000..fe6b774 --- /dev/null +++ b/src/proto/command_data.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +package command_data.v1; + +message CommandData { + repeated float data = 1; +} diff --git a/src/serverdata.rs b/src/serverdata.rs deleted file mode 100644 index 30ca6a7..0000000 --- a/src/serverdata.rs +++ /dev/null @@ -1,209 +0,0 @@ -// This file is generated by rust-protobuf 3.3.0. Do not edit -// .proto file is parsed by protoc --rust-out=... -// @generated - -// https://github.com/rust-lang/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy::all)] - -#![allow(unused_attributes)] -#![cfg_attr(rustfmt, rustfmt::skip)] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unused_results)] -#![allow(unused_mut)] - -//! Generated file from `src/proto/serverdata.proto` - -/// Generated files are compatible only with the same version -/// of protobuf runtime. -const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_3_3_0; - -// @@protoc_insertion_point(message:serverdata.v1.ServerData) -#[derive(PartialEq,Clone,Default,Debug)] -pub struct ServerData { - // message fields - // @@protoc_insertion_point(field:serverdata.v1.ServerData.value) - pub value: ::std::vec::Vec<::std::string::String>, - // @@protoc_insertion_point(field:serverdata.v1.ServerData.unit) - pub unit: ::std::string::String, - // special fields - // @@protoc_insertion_point(special_field:serverdata.v1.ServerData.special_fields) - pub special_fields: ::protobuf::SpecialFields, -} - -impl<'a> ::std::default::Default for &'a ServerData { - fn default() -> &'a ServerData { - ::default_instance() - } -} - -impl ServerData { - pub fn new() -> ServerData { - ::std::default::Default::default() - } - - fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(2); - let mut oneofs = ::std::vec::Vec::with_capacity(0); - fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( - "value", - |m: &ServerData| { &m.value }, - |m: &mut ServerData| { &mut m.value }, - )); - fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( - "unit", - |m: &ServerData| { &m.unit }, - |m: &mut ServerData| { &mut m.unit }, - )); - ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( - "ServerData", - fields, - oneofs, - ) - } -} - -impl ::protobuf::Message for ServerData { - const NAME: &'static str = "ServerData"; - - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { - while let Some(tag) = is.read_raw_tag_or_eof()? { - match tag { - 10 => { - self.value.push(is.read_string()?); - }, - 18 => { - self.unit = is.read_string()?; - }, - tag => { - ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u64 { - let mut my_size = 0; - for value in &self.value { - my_size += ::protobuf::rt::string_size(1, &value); - }; - if !self.unit.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.unit); - } - my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); - self.special_fields.cached_size().set(my_size as u32); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { - for v in &self.value { - os.write_string(1, &v)?; - }; - if !self.unit.is_empty() { - os.write_string(2, &self.unit)?; - } - os.write_unknown_fields(self.special_fields.unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn special_fields(&self) -> &::protobuf::SpecialFields { - &self.special_fields - } - - fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { - &mut self.special_fields - } - - fn new() -> ServerData { - ServerData::new() - } - - fn clear(&mut self) { - self.value.clear(); - self.unit.clear(); - self.special_fields.clear(); - } - - fn default_instance() -> &'static ServerData { - static instance: ServerData = ServerData { - value: ::std::vec::Vec::new(), - unit: ::std::string::String::new(), - special_fields: ::protobuf::SpecialFields::new(), - }; - &instance - } -} - -impl ::protobuf::MessageFull for ServerData { - fn descriptor() -> ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); - descriptor.get(|| file_descriptor().message_by_package_relative_name("ServerData").unwrap()).clone() - } -} - -impl ::std::fmt::Display for ServerData { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for ServerData { - type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; -} - -static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x1asrc/proto/serverdata.proto\x12\rserverdata.v1\"6\n\nServerData\x12\ - \x14\n\x05value\x18\x01\x20\x03(\tR\x05value\x12\x12\n\x04unit\x18\x02\ - \x20\x01(\tR\x04unitJ\xb0\x01\n\x06\x12\x04\0\0\x07\x01\n\x08\n\x01\x0c\ - \x12\x03\0\0\x12\n\x08\n\x01\x02\x12\x03\x02\0\x16\n\n\n\x02\x04\0\x12\ - \x04\x04\0\x07\x01\n\n\n\x03\x04\0\x01\x12\x03\x04\x08\x12\n\x0b\n\x04\ - \x04\0\x02\0\x12\x03\x05\x03\x1d\n\x0c\n\x05\x04\0\x02\0\x04\x12\x03\x05\ - \x03\x0b\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x05\x0c\x12\n\x0c\n\x05\x04\ - \0\x02\0\x01\x12\x03\x05\x13\x18\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x05\ - \x1b\x1c\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x06\x03\x13\n\x0c\n\x05\x04\0\ - \x02\x01\x05\x12\x03\x06\x03\t\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x06\ - \n\x0e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x06\x11\x12b\x06proto3\ -"; - -/// `FileDescriptorProto` object which was a source for this generated file -fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { - static file_descriptor_proto_lazy: ::protobuf::rt::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::Lazy::new(); - file_descriptor_proto_lazy.get(|| { - ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() - }) -} - -/// `FileDescriptor` object which allows dynamic access to files -pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { - static generated_file_descriptor_lazy: ::protobuf::rt::Lazy<::protobuf::reflect::GeneratedFileDescriptor> = ::protobuf::rt::Lazy::new(); - static file_descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::FileDescriptor> = ::protobuf::rt::Lazy::new(); - file_descriptor.get(|| { - let generated_file_descriptor = generated_file_descriptor_lazy.get(|| { - let mut deps = ::std::vec::Vec::with_capacity(0); - let mut messages = ::std::vec::Vec::with_capacity(1); - messages.push(ServerData::generated_message_descriptor_data()); - let mut enums = ::std::vec::Vec::with_capacity(0); - ::protobuf::reflect::GeneratedFileDescriptor::new_generated( - file_descriptor_proto(), - deps, - messages, - enums, - ) - }); - ::protobuf::reflect::FileDescriptor::new_generated_2(generated_file_descriptor) - }) -}