Loading system/gd/packet/parser/gen_rust.cc +3 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,9 @@ bool generate_rust_source_one_file( } for (const auto& packet_def : decls.packet_defs_queue_) { if (packet_def.second->name_.rfind("LeGetVendorCapabilitiesComplete", 0) == 0) { continue; } packet_def.second->GenRustDef(out_file); out_file << "\n\n"; } Loading system/gd/packet/parser/packet_def.cc +98 −10 Original line number Diff line number Diff line Loading @@ -745,6 +745,9 @@ void PacketDef::GenRustChildEnums(std::ostream& s) const { s << "#[derive(Debug)] "; s << "enum " << name_ << "DataChild {"; for (const auto& child : children_) { if (child->name_.rfind("LeGetVendorCapabilitiesComplete", 0) == 0) { continue; } s << child->name_ << "(Arc<" << child->name_ << "Data>),"; } s << "None,"; Loading @@ -752,6 +755,9 @@ void PacketDef::GenRustChildEnums(std::ostream& s) const { s << "#[derive(Debug)] "; s << "pub enum " << name_ << "Child {"; for (const auto& child : children_) { if (child->name_.rfind("LeGetVendorCapabilitiesComplete", 0) == 0) { continue; } s << child->name_ << "(" << child->name_ << "Packet),"; } s << "None,"; Loading Loading @@ -851,21 +857,36 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const { s << "impl " << name_ << "Data {"; s << "fn new("; bool fields_exist = GenRustStructFieldNameAndType(s); s << ") -> Self { unimplemented!();"; /* Self {"; if (!children_.empty()) { s << "child: " << name_ << "DataChild,"; } s << ") -> Self { "; s << "Self { "; GenRustStructFieldNames(s); if (fields_exist) { GenRustStructSizeField(s); if (!children_.empty()) { s << "child"; } s << "}*/ s << "}"; s << "}"; // parse function s << "fn parse(bytes: &[u8]) -> Result<Self> { unimplemented!();"; if (parent_constraints_.empty() && !children_.empty() && parent_ != nullptr) { auto constraint = FindConstraintField(); auto constraint_field = GetParamList().GetField(constraint); auto constraint_type = constraint_field->GetRustDataType(); s << "fn parse(bytes: &[u8], " << constraint << ": " << constraint_type << ") -> Result<Self> {"; } else { s << "fn parse(bytes: &[u8]) -> Result<Self> {"; } auto fields = fields_.GetFieldsWithoutTypes({ BodyField::kFieldType, FixedScalarField::kFieldType, }); /*for (auto const& field : fields) { for (auto const& field : fields) { auto start_field_offset = GetOffsetForField(field->GetName(), false); auto end_field_offset = GetOffsetForField(field->GetName(), true); Loading @@ -877,6 +898,63 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const { field->GenRustGetter(s, start_field_offset, end_field_offset); } auto payload_field = fields_.GetFieldsWithTypes({ PayloadField::kFieldType, }); Size payload_offset; if (payload_field.HasPayload()) { payload_offset = GetOffsetForField(payload_field[0]->GetName(), false); } auto constraint_name = FindConstraintField(); auto constrained_descendants = FindDescendantsWithConstraint(constraint_name); if (!children_.empty()) { s << "let child = match " << constraint_name << " {"; } for (const auto& desc : constrained_descendants) { if (desc.first->name_.rfind("LeGetVendorCapabilitiesComplete", 0) == 0) { continue; } auto desc_path = FindPathToDescendant(desc.first->name_); std::reverse(desc_path.begin(), desc_path.end()); auto constraint_field = GetParamList().GetField(constraint_name); auto constraint_type = constraint_field->GetFieldType(); if (constraint_type == EnumField::kFieldType) { auto type = std::get<std::string>(desc.second); auto variant_name = type.substr(type.find("::") + 2, type.length()); auto enum_type = type.substr(0, type.find("::")); auto enum_variant = enum_type + "::" + util::UnderscoreToCamelCase(util::ToLowerCase(variant_name)); s << enum_variant; s << " => {"; s << name_ << "DataChild::"; s << desc_path[0]->name_ << "(Arc::new("; if (desc_path[0]->parent_constraints_.empty()) { s << desc_path[0]->name_ << "Data::parse(&bytes[" << payload_offset.bytes() << "..]"; s << ", " << enum_variant << ")?))"; } else { s << desc_path[0]->name_ << "Data::parse(&bytes[" << payload_offset.bytes() << "..])?))"; } } else if (constraint_type == ScalarField::kFieldType) { s << std::get<int64_t>(desc.second) << " => {"; s << "unimplemented!();"; } s << "}\n"; } if (!constrained_descendants.empty()) { s << "_ => panic!(\"unexpected value " << "\"),"; } if (!children_.empty()) { s << "};\n"; } s << "Ok(Self {"; fields = fields_.GetFieldsWithoutTypes({ BodyField::kFieldType, Loading @@ -885,6 +963,7 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const { ReservedField::kFieldType, SizeField::kFieldType, PayloadField::kFieldType, FixedScalarField::kFieldType, }); if (fields_exist) { Loading @@ -893,9 +972,12 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const { s << fields[i]->GetName(); s << ", "; } GenRustStructSizeField(s); } s << "})}\n";*/ if (!children_.empty()) { s << "child,"; } s << "})\n"; s << "}\n"; // write_to function Loading Loading @@ -928,6 +1010,9 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const { if (!children_.empty()) { s << "match &self.child {"; for (const auto& child : children_) { if (child->name_.rfind("LeGetVendorCapabilitiesComplete", 0) == 0) { continue; } s << name_ << "DataChild::" << child->name_ << "(value) => value.write_to(buffer),"; } s << name_ << "DataChild::None => {}"; Loading @@ -945,7 +1030,7 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const { } void PacketDef::GenRustAccessStructImpls(std::ostream& s) const { if (complement_ != nullptr) { if (complement_ != nullptr && complement_->name_.rfind("LeGetVendorCapabilitiesComplete", 0) != 0) { auto complement_root = complement_->GetRootDef(); auto complement_root_accessor = util::CamelCaseToUnderScore(complement_root->name_); s << "impl CommandExpectations for " << name_ << "Packet {"; Loading Loading @@ -977,6 +1062,9 @@ void PacketDef::GenRustAccessStructImpls(std::ostream& s) const { s << " pub fn specialize(&self) -> " << name_ << "Child {"; s << " match &self." << util::CamelCaseToUnderScore(name_) << ".child {"; for (const auto& child : children_) { if (child->name_.rfind("LeGetVendorCapabilitiesComplete", 0) == 0) { continue; } s << name_ << "DataChild::" << child->name_ << "(_) => " << name_ << "Child::" << child->name_ << "(" << child->name_ << "Packet::new(self." << root_accessor << ".clone())),"; } Loading Loading @@ -1047,7 +1135,7 @@ void PacketDef::GenRustAccessStructImpls(std::ostream& s) const { } void PacketDef::GenRustBuilderStructImpls(std::ostream& s) const { if (complement_ != nullptr) { if (complement_ != nullptr && complement_->name_.rfind("LeGetVendorCapabilitiesComplete", 0) != 0) { auto complement_root = complement_->GetRootDef(); auto complement_root_accessor = util::CamelCaseToUnderScore(complement_root->name_); s << "impl CommandExpectations for " << name_ << "Builder {"; Loading system/gd/packet/parser/parent_def.cc +44 −0 Original line number Diff line number Diff line Loading @@ -521,3 +521,47 @@ bool ParentDef::HasAncestorNamed(std::string name) const { } return false; } std::string ParentDef::FindConstraintField() const { std::string res; for (const auto& child : children_) { if (!child->parent_constraints_.empty()) { return child->parent_constraints_.begin()->first; } res = child->FindConstraintField(); } return res; } std::map<const ParentDef*, const std::variant<int64_t, std::string>> ParentDef::FindDescendantsWithConstraint( std::string constraint_name) const { std::map<const ParentDef*, const std::variant<int64_t, std::string>> res; for (auto const& child : children_) { auto constraint = child->parent_constraints_.find(constraint_name); if (constraint != child->parent_constraints_.end()) { res.insert(std::pair(child, constraint->second)); } auto m = child->FindDescendantsWithConstraint(constraint_name); res.insert(m.begin(), m.end()); } return res; } std::vector<const ParentDef*> ParentDef::FindPathToDescendant(std::string descendant) const { std::vector<const ParentDef*> res; for (auto const& child : children_) { auto v = child->FindPathToDescendant(descendant); if (v.size() > 0) { res.insert(res.begin(), v.begin(), v.end()); res.push_back(child); } if (child->name_ == descendant) { res.push_back(child); return res; } } return res; } system/gd/packet/parser/parent_def.h +6 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,12 @@ class ParentDef : public TypeDef { std::vector<const ParentDef*> GetAncestors() const; std::string FindConstraintField() const; std::map<const ParentDef*, const std::variant<int64_t, std::string>> FindDescendantsWithConstraint(std::string constraint_name) const; std::vector<const ParentDef*> FindPathToDescendant(std::string descendant) const; FieldList fields_; ParentDef* parent_{nullptr}; Loading system/gd/packet/parser/util.h +15 −0 Original line number Diff line number Diff line Loading @@ -173,4 +173,19 @@ inline std::string GetRustTypeForSize(int size) { return "u64"; } inline std::string ToLowerCase(std::string value) { if (value[0] < 'A' || value[0] > 'Z') { ERROR() << value << " doesn't look like CONSTANT_CASE"; } std::ostringstream lower_case; for (unsigned char c : value) { c = std::tolower(c); lower_case << c; } return lower_case.str(); } } // namespace util Loading
system/gd/packet/parser/gen_rust.cc +3 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,9 @@ bool generate_rust_source_one_file( } for (const auto& packet_def : decls.packet_defs_queue_) { if (packet_def.second->name_.rfind("LeGetVendorCapabilitiesComplete", 0) == 0) { continue; } packet_def.second->GenRustDef(out_file); out_file << "\n\n"; } Loading
system/gd/packet/parser/packet_def.cc +98 −10 Original line number Diff line number Diff line Loading @@ -745,6 +745,9 @@ void PacketDef::GenRustChildEnums(std::ostream& s) const { s << "#[derive(Debug)] "; s << "enum " << name_ << "DataChild {"; for (const auto& child : children_) { if (child->name_.rfind("LeGetVendorCapabilitiesComplete", 0) == 0) { continue; } s << child->name_ << "(Arc<" << child->name_ << "Data>),"; } s << "None,"; Loading @@ -752,6 +755,9 @@ void PacketDef::GenRustChildEnums(std::ostream& s) const { s << "#[derive(Debug)] "; s << "pub enum " << name_ << "Child {"; for (const auto& child : children_) { if (child->name_.rfind("LeGetVendorCapabilitiesComplete", 0) == 0) { continue; } s << child->name_ << "(" << child->name_ << "Packet),"; } s << "None,"; Loading Loading @@ -851,21 +857,36 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const { s << "impl " << name_ << "Data {"; s << "fn new("; bool fields_exist = GenRustStructFieldNameAndType(s); s << ") -> Self { unimplemented!();"; /* Self {"; if (!children_.empty()) { s << "child: " << name_ << "DataChild,"; } s << ") -> Self { "; s << "Self { "; GenRustStructFieldNames(s); if (fields_exist) { GenRustStructSizeField(s); if (!children_.empty()) { s << "child"; } s << "}*/ s << "}"; s << "}"; // parse function s << "fn parse(bytes: &[u8]) -> Result<Self> { unimplemented!();"; if (parent_constraints_.empty() && !children_.empty() && parent_ != nullptr) { auto constraint = FindConstraintField(); auto constraint_field = GetParamList().GetField(constraint); auto constraint_type = constraint_field->GetRustDataType(); s << "fn parse(bytes: &[u8], " << constraint << ": " << constraint_type << ") -> Result<Self> {"; } else { s << "fn parse(bytes: &[u8]) -> Result<Self> {"; } auto fields = fields_.GetFieldsWithoutTypes({ BodyField::kFieldType, FixedScalarField::kFieldType, }); /*for (auto const& field : fields) { for (auto const& field : fields) { auto start_field_offset = GetOffsetForField(field->GetName(), false); auto end_field_offset = GetOffsetForField(field->GetName(), true); Loading @@ -877,6 +898,63 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const { field->GenRustGetter(s, start_field_offset, end_field_offset); } auto payload_field = fields_.GetFieldsWithTypes({ PayloadField::kFieldType, }); Size payload_offset; if (payload_field.HasPayload()) { payload_offset = GetOffsetForField(payload_field[0]->GetName(), false); } auto constraint_name = FindConstraintField(); auto constrained_descendants = FindDescendantsWithConstraint(constraint_name); if (!children_.empty()) { s << "let child = match " << constraint_name << " {"; } for (const auto& desc : constrained_descendants) { if (desc.first->name_.rfind("LeGetVendorCapabilitiesComplete", 0) == 0) { continue; } auto desc_path = FindPathToDescendant(desc.first->name_); std::reverse(desc_path.begin(), desc_path.end()); auto constraint_field = GetParamList().GetField(constraint_name); auto constraint_type = constraint_field->GetFieldType(); if (constraint_type == EnumField::kFieldType) { auto type = std::get<std::string>(desc.second); auto variant_name = type.substr(type.find("::") + 2, type.length()); auto enum_type = type.substr(0, type.find("::")); auto enum_variant = enum_type + "::" + util::UnderscoreToCamelCase(util::ToLowerCase(variant_name)); s << enum_variant; s << " => {"; s << name_ << "DataChild::"; s << desc_path[0]->name_ << "(Arc::new("; if (desc_path[0]->parent_constraints_.empty()) { s << desc_path[0]->name_ << "Data::parse(&bytes[" << payload_offset.bytes() << "..]"; s << ", " << enum_variant << ")?))"; } else { s << desc_path[0]->name_ << "Data::parse(&bytes[" << payload_offset.bytes() << "..])?))"; } } else if (constraint_type == ScalarField::kFieldType) { s << std::get<int64_t>(desc.second) << " => {"; s << "unimplemented!();"; } s << "}\n"; } if (!constrained_descendants.empty()) { s << "_ => panic!(\"unexpected value " << "\"),"; } if (!children_.empty()) { s << "};\n"; } s << "Ok(Self {"; fields = fields_.GetFieldsWithoutTypes({ BodyField::kFieldType, Loading @@ -885,6 +963,7 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const { ReservedField::kFieldType, SizeField::kFieldType, PayloadField::kFieldType, FixedScalarField::kFieldType, }); if (fields_exist) { Loading @@ -893,9 +972,12 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const { s << fields[i]->GetName(); s << ", "; } GenRustStructSizeField(s); } s << "})}\n";*/ if (!children_.empty()) { s << "child,"; } s << "})\n"; s << "}\n"; // write_to function Loading Loading @@ -928,6 +1010,9 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const { if (!children_.empty()) { s << "match &self.child {"; for (const auto& child : children_) { if (child->name_.rfind("LeGetVendorCapabilitiesComplete", 0) == 0) { continue; } s << name_ << "DataChild::" << child->name_ << "(value) => value.write_to(buffer),"; } s << name_ << "DataChild::None => {}"; Loading @@ -945,7 +1030,7 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const { } void PacketDef::GenRustAccessStructImpls(std::ostream& s) const { if (complement_ != nullptr) { if (complement_ != nullptr && complement_->name_.rfind("LeGetVendorCapabilitiesComplete", 0) != 0) { auto complement_root = complement_->GetRootDef(); auto complement_root_accessor = util::CamelCaseToUnderScore(complement_root->name_); s << "impl CommandExpectations for " << name_ << "Packet {"; Loading Loading @@ -977,6 +1062,9 @@ void PacketDef::GenRustAccessStructImpls(std::ostream& s) const { s << " pub fn specialize(&self) -> " << name_ << "Child {"; s << " match &self." << util::CamelCaseToUnderScore(name_) << ".child {"; for (const auto& child : children_) { if (child->name_.rfind("LeGetVendorCapabilitiesComplete", 0) == 0) { continue; } s << name_ << "DataChild::" << child->name_ << "(_) => " << name_ << "Child::" << child->name_ << "(" << child->name_ << "Packet::new(self." << root_accessor << ".clone())),"; } Loading Loading @@ -1047,7 +1135,7 @@ void PacketDef::GenRustAccessStructImpls(std::ostream& s) const { } void PacketDef::GenRustBuilderStructImpls(std::ostream& s) const { if (complement_ != nullptr) { if (complement_ != nullptr && complement_->name_.rfind("LeGetVendorCapabilitiesComplete", 0) != 0) { auto complement_root = complement_->GetRootDef(); auto complement_root_accessor = util::CamelCaseToUnderScore(complement_root->name_); s << "impl CommandExpectations for " << name_ << "Builder {"; Loading
system/gd/packet/parser/parent_def.cc +44 −0 Original line number Diff line number Diff line Loading @@ -521,3 +521,47 @@ bool ParentDef::HasAncestorNamed(std::string name) const { } return false; } std::string ParentDef::FindConstraintField() const { std::string res; for (const auto& child : children_) { if (!child->parent_constraints_.empty()) { return child->parent_constraints_.begin()->first; } res = child->FindConstraintField(); } return res; } std::map<const ParentDef*, const std::variant<int64_t, std::string>> ParentDef::FindDescendantsWithConstraint( std::string constraint_name) const { std::map<const ParentDef*, const std::variant<int64_t, std::string>> res; for (auto const& child : children_) { auto constraint = child->parent_constraints_.find(constraint_name); if (constraint != child->parent_constraints_.end()) { res.insert(std::pair(child, constraint->second)); } auto m = child->FindDescendantsWithConstraint(constraint_name); res.insert(m.begin(), m.end()); } return res; } std::vector<const ParentDef*> ParentDef::FindPathToDescendant(std::string descendant) const { std::vector<const ParentDef*> res; for (auto const& child : children_) { auto v = child->FindPathToDescendant(descendant); if (v.size() > 0) { res.insert(res.begin(), v.begin(), v.end()); res.push_back(child); } if (child->name_ == descendant) { res.push_back(child); return res; } } return res; }
system/gd/packet/parser/parent_def.h +6 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,12 @@ class ParentDef : public TypeDef { std::vector<const ParentDef*> GetAncestors() const; std::string FindConstraintField() const; std::map<const ParentDef*, const std::variant<int64_t, std::string>> FindDescendantsWithConstraint(std::string constraint_name) const; std::vector<const ParentDef*> FindPathToDescendant(std::string descendant) const; FieldList fields_; ParentDef* parent_{nullptr}; Loading
system/gd/packet/parser/util.h +15 −0 Original line number Diff line number Diff line Loading @@ -173,4 +173,19 @@ inline std::string GetRustTypeForSize(int size) { return "u64"; } inline std::string ToLowerCase(std::string value) { if (value[0] < 'A' || value[0] > 'Z') { ERROR() << value << " doesn't look like CONSTANT_CASE"; } std::ostringstream lower_case; for (unsigned char c : value) { c = std::tolower(c); lower_case << c; } return lower_case.str(); } } // namespace util