From b42a46ffbdcb4ffaf919a432ff941e6e2d2afb35 Mon Sep 17 00:00:00 2001 From: meili-bot <74670311+meili-bot@users.noreply.github.com> Date: Mon, 11 Apr 2022 15:40:00 +0200 Subject: [PATCH 1/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fbb879ed..efa64165 100644 --- a/README.md +++ b/README.md @@ -250,7 +250,7 @@ WARNING: `meilisearch-sdk` will panic if no Window is available (ex: Web extensi ## 🤖 Compatibility with Meilisearch -This package only guarantees the compatibility with the [version v0.25.0 of MeiliSearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.25.0). +This package only guarantees the compatibility with the [version v0.27.0 of MeiliSearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.27.0). ## ⚙️ Development Workflow and Contributing From e030e08ca323c501e41acd4e0a134cbf0b6b99aa Mon Sep 17 00:00:00 2001 From: meili-bot <74670311+meili-bot@users.noreply.github.com> Date: Mon, 11 Apr 2022 15:40:01 +0200 Subject: [PATCH 2/9] Update README.tpl --- README.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.tpl b/README.tpl index 14806a2a..e2f9acf6 100644 --- a/README.tpl +++ b/README.tpl @@ -97,7 +97,7 @@ WARNING: `meilisearch-sdk` will panic if no Window is available (ex: Web extensi ## 🤖 Compatibility with Meilisearch -This package only guarantees the compatibility with the [version v0.25.0 of MeiliSearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.25.0). +This package only guarantees the compatibility with the [version v0.27.0 of MeiliSearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.27.0). ## ⚙️ Development Workflow and Contributing From d55be19406c50cc656f6dd8cea277c0af44ce815 Mon Sep 17 00:00:00 2001 From: meili-bot <74670311+meili-bot@users.noreply.github.com> Date: Mon, 11 Apr 2022 20:50:45 +0200 Subject: [PATCH 3/9] Update .github/workflows/tests.yml --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b50423af..792eb478 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,7 +24,7 @@ jobs: - name: Build run: cargo build --verbose - name: Meilisearch (latest version) setup with Docker - run: docker run -d -p 7700:7700 getmeili/meilisearch:latest ./meilisearch --no-analytics --master-key=masterKey + run: docker run -d -p 7700:7700 getmeili/meilisearch:latest meilisearch --no-analytics --master-key=masterKey - name: Run tests run: cargo test --verbose From 700810c7d3a6e0d71a5a175f7b35767ec014f9eb Mon Sep 17 00:00:00 2001 From: meili-bot <74670311+meili-bot@users.noreply.github.com> Date: Mon, 11 Apr 2022 20:50:45 +0200 Subject: [PATCH 4/9] Update .github/workflows/pre-release-tests.yml --- .github/workflows/pre-release-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pre-release-tests.yml b/.github/workflows/pre-release-tests.yml index 43d69f51..d888c735 100644 --- a/.github/workflows/pre-release-tests.yml +++ b/.github/workflows/pre-release-tests.yml @@ -22,6 +22,6 @@ jobs: - name: Get the latest Meilisearch RC run: echo "MEILISEARCH_VERSION=$(curl https://raw.githubusercontent.com/meilisearch/integration-guides/main/scripts/get-latest-meilisearch-rc.sh | bash)" >> $GITHUB_ENV - name: Meilisearch (${{ env.MEILISEARCH_VERSION }}) setup with Docker - run: docker run -d -p 7700:7700 getmeili/meilisearch:${{ env.MEILISEARCH_VERSION }} ./meilisearch --master-key=masterKey --no-analytics=true + run: docker run -d -p 7700:7700 getmeili/meilisearch:${{ env.MEILISEARCH_VERSION }} meilisearch --master-key=masterKey --no-analytics=true - name: Run tests run: cargo test --verbose -- --test-threads=1 From 3aaa2a1222c2c6f22b03259d6b5d4bdc758932cb Mon Sep 17 00:00:00 2001 From: Charlotte Vermandel Date: Mon, 25 Apr 2022 19:34:35 +0200 Subject: [PATCH 5/9] Fix cropping tests --- src/search.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/search.rs b/src/search.rs index 301cbe29..63473287 100644 --- a/src/search.rs +++ b/src/search.rs @@ -452,20 +452,24 @@ mod tests { query.with_query("lorem ipsum"); query.with_attributes_to_crop(Selectors::All); let results: SearchResults = index.execute_query(&query).await?; - assert_eq!(&Document { - id: 0, - value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip".to_string(), - kind: "text".to_string() - }, results.hits[0].formatted_result.as_ref().unwrap()); + assert_eq!( + &Document { + id: 0, + value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do…" + .to_string(), + kind: "text".to_string() + }, + results.hits[0].formatted_result.as_ref().unwrap() + ); let mut query = Query::new(&index); query.with_query("lorem ipsum"); - query.with_attributes_to_crop(Selectors::Some(&[("value", Some(50)), ("kind", None)])); + query.with_attributes_to_crop(Selectors::Some(&[("value", Some(5)), ("kind", None)])); let results: SearchResults = index.execute_query(&query).await?; assert_eq!( &Document { id: 0, - value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit".to_string(), + value: "Lorem ipsum dolor sit amet…".to_string(), kind: "text".to_string() }, results.hits[0].formatted_result.as_ref().unwrap() @@ -484,7 +488,7 @@ mod tests { let results: SearchResults = index.execute_query(&query).await?; assert_eq!(&Document { id: 0, - value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip".to_string(), + value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.".to_string(), kind: "text".to_string(), }, results.hits[0].formatted_result.as_ref().unwrap()); @@ -492,12 +496,12 @@ mod tests { let mut query = Query::new(&index); query.with_query("lorem ipsum"); query.with_attributes_to_crop(Selectors::All); - query.with_crop_length(50); + query.with_crop_length(5); let results: SearchResults = index.execute_query(&query).await?; assert_eq!( &Document { id: 0, - value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit".to_string(), + value: "Lorem ipsum dolor sit amet…".to_string(), kind: "text".to_string() }, results.hits[0].formatted_result.as_ref().unwrap() From a1ff7767041fcabcae77b33c373a12221ea85d40 Mon Sep 17 00:00:00 2001 From: Charlotte Vermandel Date: Mon, 25 Apr 2022 20:44:46 +0200 Subject: [PATCH 6/9] Revert changes on meilisearch binary in docker command --- .github/workflows/pre-release-tests.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/pre-release-tests.yml b/.github/workflows/pre-release-tests.yml index 9b134cb2..d3d81944 100644 --- a/.github/workflows/pre-release-tests.yml +++ b/.github/workflows/pre-release-tests.yml @@ -16,12 +16,12 @@ jobs: name: integration-tests-against-rc runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Build - run: cargo build --verbose - - name: Get the latest Meilisearch RC - run: echo "MEILISEARCH_VERSION=$(curl https://raw.githubusercontent.com/meilisearch/integration-guides/main/scripts/get-latest-meilisearch-rc.sh | bash)" >> $GITHUB_ENV - - name: Meilisearch (${{ env.MEILISEARCH_VERSION }}) setup with Docker - run: docker run -d -p 7700:7700 getmeili/meilisearch:${{ env.MEILISEARCH_VERSION }} ./meilisearch --master-key=masterKey --no-analytics - - name: Run tests - run: cargo test --verbose -- --test-threads=1 + - uses: actions/checkout@v2 + - name: Build + run: cargo build --verbose + - name: Get the latest Meilisearch RC + run: echo "MEILISEARCH_VERSION=$(curl https://raw.githubusercontent.com/meilisearch/integration-guides/main/scripts/get-latest-meilisearch-rc.sh | bash)" >> $GITHUB_ENV + - name: Meilisearch (${{ env.MEILISEARCH_VERSION }}) setup with Docker + run: docker run -d -p 7700:7700 getmeili/meilisearch:${{ env.MEILISEARCH_VERSION }} meilisearch --master-key=masterKey --no-analytics + - name: Run tests + run: cargo test --verbose -- --test-threads=1 From 413b04a8ea180c66b16fef729cd3466c2a2d37ff Mon Sep 17 00:00:00 2001 From: cvermand <33010418+bidoubiwa@users.noreply.github.com> Date: Tue, 26 Apr 2022 15:07:05 +0200 Subject: [PATCH 7/9] Add test to ensure nested field support (#273) --- src/search.rs | 94 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 21 deletions(-) diff --git a/src/search.rs b/src/search.rs index baad8b3b..04db41ac 100644 --- a/src/search.rs +++ b/src/search.rs @@ -283,13 +283,19 @@ mod tests { use crate::{client::*, search::*}; use meilisearch_test_macro::meilisearch_test; use serde::{Deserialize, Serialize}; - use serde_json::{Map, Value, json}; + use serde_json::{json, Map, Value}; + + #[derive(Debug, Serialize, Deserialize, PartialEq)] + struct Nested { + child: String, + } #[derive(Debug, Serialize, Deserialize, PartialEq)] struct Document { id: usize, value: String, kind: String, + nested: Nested, } impl PartialEq> for Document { @@ -302,16 +308,16 @@ mod tests { async fn setup_test_index(client: &Client, index: &Index) -> Result<(), Error> { let t0 = index.add_documents(&[ - Document { id: 0, kind: "text".into(), value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.".to_string() }, - Document { id: 1, kind: "text".into(), value: "dolor sit amet, consectetur adipiscing elit".to_string() }, - Document { id: 2, kind: "title".into(), value: "The Social Network".to_string() }, - Document { id: 3, kind: "title".into(), value: "Harry Potter and the Sorcerer's Stone".to_string() }, - Document { id: 4, kind: "title".into(), value: "Harry Potter and the Chamber of Secrets".to_string() }, - Document { id: 5, kind: "title".into(), value: "Harry Potter and the Prisoner of Azkaban".to_string() }, - Document { id: 6, kind: "title".into(), value: "Harry Potter and the Goblet of Fire".to_string() }, - Document { id: 7, kind: "title".into(), value: "Harry Potter and the Order of the Phoenix".to_string() }, - Document { id: 8, kind: "title".into(), value: "Harry Potter and the Half-Blood Prince".to_string() }, - Document { id: 9, kind: "title".into(), value: "Harry Potter and the Deathly Hallows".to_string() }, + Document { id: 0, kind: "text".into(), value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.".to_string(), nested: Nested { child: "first".to_string() } }, + Document { id: 1, kind: "text".into(), value: "dolor sit amet, consectetur adipiscing elit".to_string(), nested: Nested { child: "second".to_string() } }, + Document { id: 2, kind: "title".into(), value: "The Social Network".to_string(), nested: Nested { child: "third".to_string() } }, + Document { id: 3, kind: "title".into(), value: "Harry Potter and the Sorcerer's Stone".to_string(), nested: Nested { child: "fourth".to_string() } }, + Document { id: 4, kind: "title".into(), value: "Harry Potter and the Chamber of Secrets".to_string(), nested: Nested { child: "fift".to_string() } }, + Document { id: 5, kind: "title".into(), value: "Harry Potter and the Prisoner of Azkaban".to_string(), nested: Nested { child: "sixth".to_string() } }, + Document { id: 6, kind: "title".into(), value: "Harry Potter and the Goblet of Fire".to_string(), nested: Nested { child: "seventh".to_string() } }, + Document { id: 7, kind: "title".into(), value: "Harry Potter and the Order of the Phoenix".to_string(), nested: Nested { child: "eighth".to_string() } }, + Document { id: 8, kind: "title".into(), value: "Harry Potter and the Half-Blood Prince".to_string(), nested: Nested { child: "ninth".to_string() } }, + Document { id: 9, kind: "title".into(), value: "Harry Potter and the Deathly Hallows".to_string(), nested: Nested { child: "tenth".to_string() } }, ], None).await?; let t1 = index.set_filterable_attributes(["kind", "value"]).await?; let t2 = index.set_sortable_attributes(["title"]).await?; @@ -332,6 +338,28 @@ mod tests { Ok(()) } + #[meilisearch_test] + async fn test_query_string_on_nested_field(client: Client, index: Index) -> Result<(), Error> { + setup_test_index(&client, &index).await?; + + let results: SearchResults = + index.search().with_query("second").execute().await?; + + assert_eq!( + &Document { + id: 1, + value: "dolor sit amet, consectetur adipiscing elit".to_string(), + kind: "text".to_string(), + nested: Nested { + child: "second".to_string() + } + }, + &results.hits[0].result + ); + + Ok(()) + } + #[meilisearch_test] async fn test_query_limit(client: Client, index: Index) -> Result<(), Error> { setup_test_index(&client, &index).await?; @@ -457,7 +485,10 @@ mod tests { id: 0, value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do…" .to_string(), - kind: "text".to_string() + kind: "text".to_string(), + nested: Nested { + child: "first".to_string() + } }, results.hits[0].formatted_result.as_ref().unwrap() ); @@ -470,7 +501,10 @@ mod tests { &Document { id: 0, value: "Lorem ipsum dolor sit amet…".to_string(), - kind: "text".to_string() + kind: "text".to_string(), + nested: Nested { + child: "first".to_string() + } }, results.hits[0].formatted_result.as_ref().unwrap() ); @@ -490,6 +524,7 @@ mod tests { id: 0, value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.".to_string(), kind: "text".to_string(), + nested: Nested { child: "first".to_string() } }, results.hits[0].formatted_result.as_ref().unwrap()); @@ -502,7 +537,10 @@ mod tests { &Document { id: 0, value: "Lorem ipsum dolor sit amet…".to_string(), - kind: "text".to_string() + kind: "text".to_string(), + nested: Nested { + child: "first".to_string() + } }, results.hits[0].formatted_result.as_ref().unwrap() ); @@ -521,7 +559,10 @@ mod tests { &Document { id: 1, value: "dolor sit amet, consectetur adipiscing elit".to_string(), - kind: "text".to_string() + kind: "text".to_string(), + nested: Nested { + child: "first".to_string() + } }, results.hits[0].formatted_result.as_ref().unwrap(), ); @@ -534,7 +575,10 @@ mod tests { &Document { id: 1, value: "dolor sit amet, consectetur adipiscing elit".to_string(), - kind: "text".to_string() + kind: "text".to_string(), + nested: Nested { + child: "first".to_string() + } }, results.hits[0].formatted_result.as_ref().unwrap() ); @@ -577,15 +621,20 @@ mod tests { } #[meilisearch_test] - async fn test_generate_tenant_token_from_client(client: Client, index: Index) -> Result<(), Error> { - use crate::key::{KeyBuilder, Action}; + async fn test_generate_tenant_token_from_client( + client: Client, + index: Index, + ) -> Result<(), Error> { + use crate::key::{Action, KeyBuilder}; setup_test_index(&client, &index).await?; let key = KeyBuilder::new("key for generate_tenant_token test") .with_action(Action::All) .with_index("*") - .create(&client).await.unwrap(); + .create(&client) + .await + .unwrap(); let allowed_client = Client::new("http://localhost:7700", key.key); let search_rules = vec![ @@ -597,10 +646,13 @@ mod tests { ]; for rules in search_rules { - let token = allowed_client.generate_tenant_token(rules, None, None).expect("Cannot generate tenant token."); + let token = allowed_client + .generate_tenant_token(rules, None, None) + .expect("Cannot generate tenant token."); let new_client = Client::new("http://localhost:7700", token); - let result: SearchResults = new_client.index(index.uid.to_string()) + let result: SearchResults = new_client + .index(index.uid.to_string()) .search() .execute() .await?; From a5d74bd69e74ce70ae46aadfbdd1bf319e95c127 Mon Sep 17 00:00:00 2001 From: cvermand <33010418+bidoubiwa@users.noreply.github.com> Date: Wed, 27 Apr 2022 14:48:42 +0200 Subject: [PATCH 8/9] Update the code samples (#277) --- .code-samples.meilisearch.yaml | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index 404f7b6c..b3ed1dab 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -263,7 +263,18 @@ search_parameter_guide_crop_1: |- let results: SearchResults = client.index("movies").search() .with_query("shifu") .with_attributes_to_crop(Selectors::Some(&[("overview", None)])) - .with_crop_length(10) + .with_crop_length(5) + .execute() + .await + .unwrap(); + + // Get the formatted results + let formatted_results: Vec<&Movie> = results.hits.iter().map(|r| r.formatted_result.as_ref().unwrap()).collect(); +search_parameter_guide_crop_marker_1: |- + let results: SearchResults = client.index("movies").search() + .with_query("shifu") + .with_attributes_to_crop(Selectors::Some(&[("overview", None)])) + .with_crop_marker("[…]") .execute() .await .unwrap(); @@ -278,6 +289,18 @@ search_parameter_guide_highlight_1: |- .await .unwrap(); + // Get the formatted results + let formatted_results: Vec<&Movie> = results.hits.iter().map(|r| r.formatted_result.as_ref().unwrap()).collect(); +search_parameter_guide_highlight_tag_1: |- + let results: SearchResults = client.index("movies").search() + .with_query("winter feast") + .with_attributes_to_highlight(Selectors::Some(&["overview"])) + .with_highlight_pre_tag("") + .with_highlight_post_tag("") + .execute() + .await + .unwrap(); + // Get the formatted results let formatted_results: Vec<&Movie> = results.hits.iter().map(|r| r.formatted_result.as_ref().unwrap()).collect(); search_parameter_guide_matches_1: |- From 319cf52874544acdf96461b9726cbcc34b4aea07 Mon Sep 17 00:00:00 2001 From: cvermand <33010418+bidoubiwa@users.noreply.github.com> Date: Thu, 28 Apr 2022 14:19:31 +0200 Subject: [PATCH 9/9] Add new search parameters highlightPreTag, highlightPostTag and cropMarker (#274) * Add test to ensure nested field support * Add new search parameters highlightPreTag, highlightPostTag and cropMarker * Improve commens --- src/search.rs | 103 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 99 insertions(+), 4 deletions(-) diff --git a/src/search.rs b/src/search.rs index 04db41ac..eaaeed31 100644 --- a/src/search.rs +++ b/src/search.rs @@ -173,18 +173,36 @@ pub struct Query<'a> { #[serde(skip_serializing_if = "Option::is_none")] #[serde(serialize_with = "serialize_attributes_to_crop_with_wildcard")] pub attributes_to_crop: Option]>>, - /// Number of characters to keep on each side of the start of the matching word. + /// Maximum number of words including the matched query term(s) contained in the returned cropped value(s). /// See [attributes_to_crop](#structfield.attributes_to_crop). /// - /// Default: `200` + /// Default: `10` #[serde(skip_serializing_if = "Option::is_none")] pub crop_length: Option, + /// Marker at the start and the end of a cropped value. + /// ex: `...middle of a crop...` + /// + /// Default: `...` + #[serde(skip_serializing_if = "Option::is_none")] + pub crop_marker: Option<&'a str>, /// Attributes whose values will contain **highlighted matching terms**. /// /// Can be set to a [wildcard value](enum.Selectors.html#variant.All) that will select all existing attributes. #[serde(skip_serializing_if = "Option::is_none")] #[serde(serialize_with = "serialize_with_wildcard")] pub attributes_to_highlight: Option>, + /// Tag in front of a highlighted term. + /// ex: `hello world` + /// + /// Default: `` + #[serde(skip_serializing_if = "Option::is_none")] + pub highlight_pre_tag: Option<&'a str>, + /// Tag after the a highlighted term. + /// ex: `hello world` + /// + /// Default: `` + #[serde(skip_serializing_if = "Option::is_none")] + pub highlight_post_tag: Option<&'a str>, /// Defines whether an object that contains information about the matches should be returned or not. /// /// Default: `false` @@ -206,7 +224,10 @@ impl<'a> Query<'a> { attributes_to_retrieve: None, attributes_to_crop: None, crop_length: None, + crop_marker: None, attributes_to_highlight: None, + highlight_pre_tag: None, + highlight_post_tag: None, matches: None, } } @@ -251,6 +272,14 @@ impl<'a> Query<'a> { self.attributes_to_crop = Some(attributes_to_crop); self } + pub fn with_crop_length<'b>(&'b mut self, crop_length: usize) -> &'b mut Query<'a> { + self.crop_length = Some(crop_length); + self + } + pub fn with_crop_marker<'b>(&'b mut self, crop_marker: &'a str) -> &'b mut Query<'a> { + self.crop_marker = Some(crop_marker); + self + } pub fn with_attributes_to_highlight<'b>( &'b mut self, attributes_to_highlight: Selectors<&'a [&'a str]>, @@ -258,8 +287,18 @@ impl<'a> Query<'a> { self.attributes_to_highlight = Some(attributes_to_highlight); self } - pub fn with_crop_length<'b>(&'b mut self, crop_length: usize) -> &'b mut Query<'a> { - self.crop_length = Some(crop_length); + pub fn with_highlight_pre_tag<'b>( + &'b mut self, + highlight_pre_tag: &'a str, + ) -> &'b mut Query<'a> { + self.highlight_pre_tag = Some(highlight_pre_tag); + self + } + pub fn with_highlight_post_tag<'b>( + &'b mut self, + highlight_post_tag: &'a str, + ) -> &'b mut Query<'a> { + self.highlight_post_tag = Some(highlight_post_tag); self } pub fn with_matches<'b>(&'b mut self, matches: bool) -> &'b mut Query<'a> { @@ -547,6 +586,62 @@ mod tests { Ok(()) } + #[meilisearch_test] + async fn test_query_customized_crop_marker(client: Client, index: Index) -> Result<(), Error> { + setup_test_index(&client, &index).await?; + + let mut query = Query::new(&index); + query.with_query("sed do eiusmod"); + query.with_attributes_to_crop(Selectors::All); + query.with_crop_length(6); + query.with_crop_marker("(ꈍᴗꈍ)"); + + let results: SearchResults = index.execute_query(&query).await?; + + assert_eq!( + &Document { + id: 0, + value: "(ꈍᴗꈍ)consectetur adipiscing elit, sed do eiusmod(ꈍᴗꈍ)".to_string(), + kind: "text".to_string(), + nested: Nested { + child: "first".to_string() + } + }, + results.hits[0].formatted_result.as_ref().unwrap() + ); + Ok(()) + } + + #[meilisearch_test] + async fn test_query_customized_highlight_pre_tag( + client: Client, + index: Index, + ) -> Result<(), Error> { + setup_test_index(&client, &index).await?; + + let mut query = Query::new(&index); + query.with_query("Social"); + query.with_attributes_to_highlight(Selectors::All); + query.with_highlight_pre_tag("(⊃。•́‿•̀。)⊃ "); + query.with_highlight_post_tag(" ⊂(´• ω •`⊂)"); + + let results: SearchResults = index.execute_query(&query).await?; + dbg!(&results); + assert_eq!( + &Document { + id: 2, + value: "The (⊃。•́‿•̀。)⊃ Social ⊂(´• ω •`⊂) Network".to_string(), + kind: "title".to_string(), + nested: Nested { + child: "third".to_string() + } + }, + results.hits[0].formatted_result.as_ref().unwrap() + ); + + Ok(()) + } + #[meilisearch_test] async fn test_query_attributes_to_highlight(client: Client, index: Index) -> Result<(), Error> { setup_test_index(&client, &index).await?;