@@ -56,18 +56,21 @@ pub async fn search(
5656
5757/// Component data in search results.
5858#[ derive( Serialize , Deserialize , Debug , ToSchema ) ]
59+ #[ serde( rename_all = "camelCase" ) ]
5960pub struct ComponentSearchResult {
60- #[ schema( value_type = String , example = "01H9ZQD35JPMBGHH69BT0Q79AA" ) ]
61+ #[ schema( example = "01H9ZQD35JPMBGHH69BT0Q79AA" , value_type = String ) ]
6162 pub id : ComponentId ,
62- #[ schema( value_type = String , example = "MyInstance" ) ]
63+ #[ schema( example = "MyInstance" ) ]
6364 pub name : String ,
6465 pub schema : ComponentSearchResultSchema ,
66+ pub highlighted_attributes : HashMap < String , serde_json:: Value > ,
6567}
6668
6769/// The schema for a component in search results.
6870#[ derive( Serialize , Deserialize , Debug , ToSchema ) ]
71+ #[ serde( rename_all = "camelCase" ) ]
6972pub struct ComponentSearchResultSchema {
70- #[ schema( value_type = String , example = "AWS::EC2::Instance" ) ]
73+ #[ schema( example = "AWS::EC2::Instance" ) ]
7174 pub name : String ,
7275}
7376
@@ -80,13 +83,15 @@ async fn match_component(
8083 query : Arc < SearchQuery > ,
8184) -> Result < Option < ComponentSearchResult > > {
8285 let attribute_tree = attribute_tree_mv ( frigg, workspace_pk, index_ref) . await ?;
83- if match_attribute_tree ( & attribute_tree, & query) {
86+ let mut highlighted_attributes = HashMap :: new ( ) ;
87+ if match_attribute_tree ( & attribute_tree, & query, & mut highlighted_attributes) {
8488 Ok ( Some ( ComponentSearchResult {
8589 id : attribute_tree. id ,
8690 name : attribute_tree. component_name ,
8791 schema : ComponentSearchResultSchema {
8892 name : attribute_tree. schema_name ,
8993 } ,
94+ highlighted_attributes,
9095 } ) )
9196 } else {
9297 Ok ( None )
@@ -97,26 +102,38 @@ async fn match_component(
97102///
98103/// This is called once for each term in the query, and the results are combined according to
99104/// query rules (AND, OR, NOT).
100- fn match_attribute_tree ( attribute_tree : & AttributeTreeForSearch , query : & SearchQuery ) -> bool {
105+ fn match_attribute_tree (
106+ attribute_tree : & AttributeTreeForSearch ,
107+ query : & SearchQuery ,
108+ highlighted_attributes : & mut HashMap < String , serde_json:: Value > ,
109+ ) -> bool {
101110 match query {
102111 SearchQuery :: MatchValue ( term) => {
103112 term. match_str ( & attribute_tree. component_name )
104113 || term. match_str ( & attribute_tree. schema_name )
105114 || term. match_ulid ( attribute_tree. id )
106115 }
107- // TODO support schema:, category:, component: and id:
108- SearchQuery :: MatchAttr { name, terms } => attribute_tree
109- . attribute_values
110- . values ( )
111- . filter ( |av| match_attr_path ( & av. path , name) )
112- . any ( |av| match_attr_value ( & av. value , terms) ) ,
116+
117+ SearchQuery :: MatchAttr { name, terms } => {
118+ // TODO support schema:, category:, component: and id:
119+
120+ for av in attribute_tree. attribute_values . values ( ) {
121+ if match_attr_path ( & av. path , name) && match_attr_value ( & av. value , terms) {
122+ highlighted_attributes. insert ( av. path . clone ( ) , av. value . clone ( ) ) ;
123+ return true ;
124+ }
125+ }
126+ false
127+ }
113128 SearchQuery :: And ( queries) => queries
114129 . iter ( )
115- . all ( |query| match_attribute_tree ( attribute_tree, query) ) ,
130+ . all ( |query| match_attribute_tree ( attribute_tree, query, highlighted_attributes ) ) ,
116131 SearchQuery :: Or ( queries) => queries
117132 . iter ( )
118- . any ( |query| match_attribute_tree ( attribute_tree, query) ) ,
119- SearchQuery :: Not ( sub_query) => !match_attribute_tree ( attribute_tree, sub_query) ,
133+ . any ( |query| match_attribute_tree ( attribute_tree, query, highlighted_attributes) ) ,
134+ SearchQuery :: Not ( sub_query) => {
135+ !match_attribute_tree ( attribute_tree, sub_query, highlighted_attributes)
136+ }
120137 SearchQuery :: All => true ,
121138 }
122139}
0 commit comments