Loading system/gd/packet/parser/enum_def.h +2 −0 Original line number Diff line number Diff line Loading @@ -39,4 +39,6 @@ class EnumDef : public TypeDef { // data std::map<uint32_t, std::string> constants_; std::set<std::string> entries_; EnumDef* try_from_enum_ = nullptr; }; system/gd/packet/parser/enum_gen.cc +21 −0 Original line number Diff line number Diff line Loading @@ -67,4 +67,25 @@ void EnumGen::GenRustDef(std::ostream& stream) { stream << util::ConstantCaseToCamelCase(pair.second) << " = 0x" << std::hex << pair.first << std::dec << ","; } stream << "}"; if (e_.try_from_enum_ != nullptr) { std::vector<std::string> other_items; for (const auto& pair : e_.try_from_enum_->constants_) { other_items.push_back(pair.second); } stream << "impl TryFrom<" << e_.try_from_enum_->name_ << "> for " << e_.name_ << " {"; stream << "type Error = &'static str;"; stream << "fn try_from(value: " << e_.try_from_enum_->name_ << ") -> std::result::Result<Self, Self::Error> {"; stream << "match value {"; for (const auto& pair : e_.constants_) { if (std::find(other_items.begin(), other_items.end(), pair.second) == other_items.end()) { continue; } auto constant_name = util::ConstantCaseToCamelCase(pair.second); stream << e_.try_from_enum_->name_ << "::" << constant_name << " => Ok(" << e_.name_ << "::" << constant_name << "),"; } stream << "_ => Err(\"No mapping for provided key\"),"; stream << "}}}"; } } system/gd/packet/parser/fields/packet_field.h +4 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,10 @@ class PacketField : public Loggable { virtual void GenRustWriter(std::ostream& s, Size start_offset, Size end_offset) const = 0; virtual bool GetterIsByRef() const { return true; } private: ParseLocation loc_; std::string name_; Loading system/gd/packet/parser/fields/scalar_field.h +4 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,10 @@ class ScalarField : public PacketField { void GenRustWriter(std::ostream& s, Size start_offset, Size end_offset) const override; virtual bool GetterIsByRef() const override { return false; } private: const int size_; }; system/gd/packet/parser/gen_rust.cc +54 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,60 @@ bool generate_rust_source_one_file( out_file << "// @generated rust packets from " << input_file.filename().string() << "\n\n"; generate_rust_packet_preamble(out_file); if (input_filename == "hci_packets") { out_file << "pub trait CommandExpectations { " << "type ResponseType;" << "fn _to_response_type(pkt: EventPacket) -> Self::ResponseType;" << "}"; for (const auto& packet_def : decls.packet_defs_queue_) { auto packet = packet_def.second; if (!packet->HasAncestorNamed("Command")) { continue; } auto constraint = packet->parent_constraints_.find("op_code"); if (constraint == packet->parent_constraints_.end()) { continue; } auto opcode = std::get<std::string>(constraint->second); for (const auto& other_packet_def : decls.packet_defs_queue_) { auto other_packet = other_packet_def.second; bool command_status = other_packet->HasAncestorNamed("CommandStatus"); bool command_complete = other_packet->HasAncestorNamed("CommandComplete"); if (!command_status && !command_complete) { continue; } auto other_constraint = other_packet->parent_constraints_.find("command_op_code"); if (other_constraint == other_packet->parent_constraints_.end()) { continue; } auto other_opcode = std::get<std::string>(other_constraint->second); if (opcode == other_opcode) { packet->complement_ = other_packet; break; } } } EnumDef* opcode = nullptr; EnumDef* opcode_index = nullptr; for (const auto& e : decls.type_defs_queue_) { if (e.second->GetDefinitionType() == TypeDef::Type::ENUM) { auto* enum_def = dynamic_cast<EnumDef*>(e.second); if (enum_def->name_ == "OpCode") { opcode = enum_def; } else if (enum_def->name_ == "OpCodeIndex") { opcode_index = enum_def; } } } if (opcode_index != nullptr && opcode != nullptr) { opcode_index->try_from_enum_ = opcode; out_file << "use std::convert::TryFrom;"; } } for (const auto& e : decls.type_defs_queue_) { if (e.second->GetDefinitionType() == TypeDef::Type::ENUM) { Loading Loading
system/gd/packet/parser/enum_def.h +2 −0 Original line number Diff line number Diff line Loading @@ -39,4 +39,6 @@ class EnumDef : public TypeDef { // data std::map<uint32_t, std::string> constants_; std::set<std::string> entries_; EnumDef* try_from_enum_ = nullptr; };
system/gd/packet/parser/enum_gen.cc +21 −0 Original line number Diff line number Diff line Loading @@ -67,4 +67,25 @@ void EnumGen::GenRustDef(std::ostream& stream) { stream << util::ConstantCaseToCamelCase(pair.second) << " = 0x" << std::hex << pair.first << std::dec << ","; } stream << "}"; if (e_.try_from_enum_ != nullptr) { std::vector<std::string> other_items; for (const auto& pair : e_.try_from_enum_->constants_) { other_items.push_back(pair.second); } stream << "impl TryFrom<" << e_.try_from_enum_->name_ << "> for " << e_.name_ << " {"; stream << "type Error = &'static str;"; stream << "fn try_from(value: " << e_.try_from_enum_->name_ << ") -> std::result::Result<Self, Self::Error> {"; stream << "match value {"; for (const auto& pair : e_.constants_) { if (std::find(other_items.begin(), other_items.end(), pair.second) == other_items.end()) { continue; } auto constant_name = util::ConstantCaseToCamelCase(pair.second); stream << e_.try_from_enum_->name_ << "::" << constant_name << " => Ok(" << e_.name_ << "::" << constant_name << "),"; } stream << "_ => Err(\"No mapping for provided key\"),"; stream << "}}}"; } }
system/gd/packet/parser/fields/packet_field.h +4 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,10 @@ class PacketField : public Loggable { virtual void GenRustWriter(std::ostream& s, Size start_offset, Size end_offset) const = 0; virtual bool GetterIsByRef() const { return true; } private: ParseLocation loc_; std::string name_; Loading
system/gd/packet/parser/fields/scalar_field.h +4 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,10 @@ class ScalarField : public PacketField { void GenRustWriter(std::ostream& s, Size start_offset, Size end_offset) const override; virtual bool GetterIsByRef() const override { return false; } private: const int size_; };
system/gd/packet/parser/gen_rust.cc +54 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,60 @@ bool generate_rust_source_one_file( out_file << "// @generated rust packets from " << input_file.filename().string() << "\n\n"; generate_rust_packet_preamble(out_file); if (input_filename == "hci_packets") { out_file << "pub trait CommandExpectations { " << "type ResponseType;" << "fn _to_response_type(pkt: EventPacket) -> Self::ResponseType;" << "}"; for (const auto& packet_def : decls.packet_defs_queue_) { auto packet = packet_def.second; if (!packet->HasAncestorNamed("Command")) { continue; } auto constraint = packet->parent_constraints_.find("op_code"); if (constraint == packet->parent_constraints_.end()) { continue; } auto opcode = std::get<std::string>(constraint->second); for (const auto& other_packet_def : decls.packet_defs_queue_) { auto other_packet = other_packet_def.second; bool command_status = other_packet->HasAncestorNamed("CommandStatus"); bool command_complete = other_packet->HasAncestorNamed("CommandComplete"); if (!command_status && !command_complete) { continue; } auto other_constraint = other_packet->parent_constraints_.find("command_op_code"); if (other_constraint == other_packet->parent_constraints_.end()) { continue; } auto other_opcode = std::get<std::string>(other_constraint->second); if (opcode == other_opcode) { packet->complement_ = other_packet; break; } } } EnumDef* opcode = nullptr; EnumDef* opcode_index = nullptr; for (const auto& e : decls.type_defs_queue_) { if (e.second->GetDefinitionType() == TypeDef::Type::ENUM) { auto* enum_def = dynamic_cast<EnumDef*>(e.second); if (enum_def->name_ == "OpCode") { opcode = enum_def; } else if (enum_def->name_ == "OpCodeIndex") { opcode_index = enum_def; } } } if (opcode_index != nullptr && opcode != nullptr) { opcode_index->try_from_enum_ = opcode; out_file << "use std::convert::TryFrom;"; } } for (const auto& e : decls.type_defs_queue_) { if (e.second->GetDefinitionType() == TypeDef::Type::ENUM) { Loading