meilisearch / meilisearch/meilisearch-rust
Documentation Error: Rust Tutorial Has Compilation Issues
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 434
- Forks
- 114
- PR merge metrics
- No merged PRs in 30d
Description
Hello MeiliSearch team,
First of all, thank you for creating such a wonderful tool!
Summary
I'm following the Getting started with self-hosted Meilisearch tutorial using the Rust SDK. However, I ran into multiple compilation errors when following the tutorial code exactly as written.
Steps to Reproduce
- Follow the Rust code examples in the "Add documents" section of the tutorial
- Copy the code exactly as shown
- Run
cargo buildandcargo run
The Tutorial Code
The documentation shows this code:
// In your .toml file:
[dependencies]
meilisearch-sdk = "0.32.0"
# futures: because we want to block on futures
futures = "0.3"
# serde: required if you are going to use documents
serde = { version="1.0", features = ["derive"] }
# serde_json: required in some parts of this guide
serde_json = "1.0"
// In your .rs file:
// Documents in the Rust library are strongly typed
#[derive(Serialize, Deserialize)]
struct Movie {
id: i64,
title: String,
poster: String,
overview: String,
release_date: i64,
genres: Vec<String>
}
// You will often need this `Movie` struct in other parts of this documentation. (you will have to change it a bit sometimes)
// You can also use schemaless values, by putting a `serde_json::Value` inside your own struct like this:
#[derive(Serialize, Deserialize)]
struct Movie {
id: i64,
#[serde(flatten)]
value: serde_json::Value,
}
// Then, add documents into the index:
use meilisearch_sdk::{
indexes::*,
client::*,
search::*,
settings::*
};
use serde::{Serialize, Deserialize};
use std::{io::prelude::*, fs::File};
use futures::executor::block_on;
fn main() { block_on(async move {
let client = Client::new("http://localhost:7700", Some("aSampleMasterKey"));
// Reading and parsing the file
let mut file = File::open("movies.json")
.unwrap();
let mut content = String::new();
file
.read_to_string(&mut content)
.unwrap();
let movies_docs: Vec<Movie> = serde_json::from_str(&content)
.unwrap();
// Adding documents
client
.index("movies")
.add_documents(&movies_docs, None)
.await
.unwrap();
})}
What I Experienced
When following the tutorial step by step, I encountered three issues. I'd like to share them in case they might be helpful for improving the documentation:
Issue 1: Client::new() Returns a Result and Needs Error Handling
The tutorial code uses:
let client = Client::new("http://localhost:7700", Some("aSampleMasterKey"));
This causes a compilation error:
error[E0599]: no method named `index` found for enum `Result<T, E>` in the current scope
--> src/main.rs:28:14
|
27 | / client
28 | | .index("movies")
| | ^^^^^ method not found in `Result<meilisearch_sdk::client::Client, meilisearch_sdk::errors::Error>`
|
note: the method `index` exists on the type `meilisearch_sdk::client::Client`
Reason: Client::new() returns a Result<Client, Error>, not a Client directly.
Possible fix: One way to address this would be to add error handling:
let client = Client::new("http://localhost:7700", Some("aSampleMasterKey"))
.unwrap();
Issue 2: Runtime Error - No Tokio Reactor Available
After fixing Issue 1, the code compiles but panics at runtime:
thread 'main' panicked at /Users/.../hyper-util-0.1.20/src/client/legacy/connect/dns.rs:119:24:
there is no reactor running, must be called from the context of a Tokio 1.x runtime
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Reason: The meilisearch-sdk internally uses libraries that require a full Tokio runtime, but futures::executor::block_on doesn't provide one. It only provides a basic executor without the reactor needed for async I/O operations.
Possible fix: Perhaps replacing futures with tokio and using #[tokio::main] might help resolve this issue.
Issue 3: get_task() Cannot Accept Raw u32 Values
The documentation shows checking task status with:
client
.get_task(0)
.await
.unwrap();
However, this code fails to compile with the following error:
error[E0277]: the trait bound `{integer}: AsRef<u32>` is not satisfied
--> src/main.rs:22:32
|
22 | let task = client.get_task(0).await.unwrap();
| -------- ^ the trait `AsRef<u32>` is not implemented for `{integer}`
| |
| required by a bound introduced by this call
Reason: The get_task() method signature requires impl AsRef<u32>, but Rust's standard library doesn't implement AsRef<u32> for the u32 type itself.
Possible approach (might work well): One way could be to use the TaskInfo returned from operations directly, and wait for the task to complete(Otherwise, it might be always showing Processing):
use tokio::time::{sleep, Duration};
// Adding documents returns TaskInfo which implements AsRef<u32>
let task_info = client
.index("movies")
.add_documents(&movies_docs, None)
.await
.unwrap();
println!("Task enqueued with UID: {}", task_info.get_task_uid());
// Wait for the task to be processed (since tasks are asynchronous)
sleep(Duration::from_secs(2)).await;
// Can pass task_info directly to get_task
let task = client.get_task(task_info).await.unwrap();
println!("Task status: {:#?}", task);
Alternative approach: Another option could be to create a simple wrapper type that implements AsRef<u32> and
we cound retrieve the status of the task in another run:
// Define a wrapper type
struct TaskId(u32);
impl AsRef<u32> for TaskId {
fn as_ref(&self) -> &u32 {
&self.0
}
}
// Use the wrapper
let task = client.get_task(TaskId(0)).await.unwrap();
Possible Solution
One way to address all three issues might be to update both Cargo.toml and the code as follows:
Cargo.toml
[dependencies]
meilisearch-sdk = "0.32.0"
tokio = { version = "1", features = ["full"] } # Replace futures with tokio
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
src/main.rs
use meilisearch_sdk::client::*;
use serde::{Serialize, Deserialize};
use std::{fs::File, io::prelude::*};
use tokio::time::{Duration, sleep};
#[derive(Serialize, Deserialize, Debug)]
struct Movie {
id: i64,
title: String,
poster: String,
overview: String,
release_date: i64,
genres: Vec<String>,
}
// Optional: wrapper for using raw u32 values with get_task
struct TaskId(u32);
impl AsRef<u32> for TaskId {
fn as_ref(&self) -> &u32 {
&self.0
}
}
#[tokio::main]
async fn main() {
let client = Client::new("http://localhost:7700", Some("aSampleMasterKey"))
.unwrap(); // Addresses Issue 1
// Reading and parsing the file
let mut file = File::open("movies.json").unwrap();
let mut content = String::new();
file.read_to_string(&mut content).unwrap();
let movies_docs: Vec<Movie> = serde_json::from_str(&content).unwrap();
println!("Loaded {} movies", movies_docs.len());
// Adding documents
let task_info = client
.index("movies")
.add_documents(&movies_docs, None)
.await
.unwrap();
println!("Documents added! Task UID: {}", task_info.get_task_uid());
// Addresses Issue 3: Waiting for task completion, then checking status
sleep(Duration::from_secs(2)).await;
let task = client.get_task(task_info).await.unwrap();
println!("Task status: {:#?}", task);
// Alternative for Issue 3: Using TaskId wrapper for raw u32
// let task = client.get_task(TaskId(0)).await.unwrap();
}
Environment
- Rust version: 1.91.0 (or latest stable)
- meilisearch 1.35.0
- meilisearch-sdk: 0.32.0
- OS: macOS Tahoe 26.2
Additional Notes
I just started learning Rust not long ago and I'm a complete newbie. I'm playing around with Meilisearch to improve my Rust skills by reading your code. If I've misunderstood something or made an error in my analysis, please feel free to correct me or close this issue.
I hope this feedback helps improve the documentation for other newcomers! Thank you for your time and for this amazing project. 🙏
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the Rust tutorial from the linked Getting started page using the shown Cargo.toml and src/main.rs examples with meilisearch-sdk 0.32.0. Start by checking the SDK signatures for Client::new and get_task, then run cargo build and cargo run with the documented runtime. Done means the dependency list and examples compile and execute without the reported runtime or task lookup errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100