How to Handle Embedding Type Conversion in Rust (with OpenAI API Example)
When working with embeddings and machine learning models in Rust, you may encounter a situation where type conversion is required—for instance, casting f64 values to f32. In this article, we’ll break down an example of embedding generation using the OpenAI API and Rig’s EmbeddingsBuilder. We’ll also explain why and how this type conversion is necessary.

Handle Embedding Type Conversion in Rust
Understanding the Example Code
Here’s the snippet of Rust (Rig.rs) code we’re analyzing:
let model = openai_client.embedding_model(TEXT_EMBEDDING_ADA_002);
let documents = EmbeddingsBuilder::new(model.clone())
.document(Word {
id: "0981d983-a5f8-49eb-89ea-f7d3b2196d2e".to_string(),
definition: "Definition of a *flurbo*: A flurbo is a green alien that lives on cold planets".to_string(),
})?
.document(Word {
id: "62a36d43-80b6-4fd6-990c-f75bb02287d1".to_string(),
definition: "Definition of a *glarb-glarb*: A glarb-glarb is an ancient tool used by the ancestors of the inhabitants of planet Jiro to farm the land.".to_string(),
})?
.document(Word {
id: "f9e17d59-32e5-440c-be02-b2759a654824".to_string(),
definition: "Definition of a *linglingdong*: A term used by inhabitants of the far side of the moon to describe humans.".to_string(),
})?
.build()
.await?;
In this code, the EmbeddingsBuilder processes documents with definitions, generating embeddings for each document. However, you might run into a need to convert the embedding values from one type to another. Let’s explore why that happens and how to resolve it.
Why Does Type Conversion Happen?
The type conversion issue typically arises because:
- API Output Types:
- Many machine learning APIs, such as OpenAI’s embedding models, return values as
f64(double-precision floating-point numbers) for accuracy.
- Many machine learning APIs, such as OpenAI’s embedding models, return values as
- Library Requirements:
- Downstream processing libraries (e.g.,
EmbeddingsBuilder) may require embeddings to be represented asf32(single-precision floating-point numbers) for efficiency.
- Downstream processing libraries (e.g.,
Rust is strict about type safety, so it doesn’t automatically convert between numerical types. If the embeddings returned are f64 but the library expects f32, you’ll encounter a compiler error.
How to Identify the Need for Conversion
There are two main ways the programmer knows type conversion is required:
- Reading API Documentation:
- The OpenAI API documentation might specify that the embeddings returned are vectors of
f64. For example: “The embedding output is a vector off64values for each input text.” - Similarly, the
EmbeddingsBuilderdocumentation may state: “This builder expects vectors off32values for efficiency.”
- The OpenAI API documentation might specify that the embeddings returned are vectors of
- Rust Compiler Feedback:
- If the programmer attempts to pass
f64values to a function that expectsf32, the Rust compiler will emit a clear error:error[E0308]: mismatched types --> src/main.rs:45:22 | 45 | .document(vec![0.25f64, 0.18f64, 0.73f64])? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `f32`, found `f64` help: you can cast each value to `f32` using `as f32`
- If the programmer attempts to pass
Implementing the Conversion
To resolve the issue, the programmer must explicitly cast the f64 values to f32. Here’s how it can be done:
let embeddings = vec![
vec![0.25f64, 0.18f64, 0.73f64],
vec![0.11f64, 0.42f64, 0.67f64],
];
let embeddings_f32: Vec<Vec<f32>> = embeddings
.into_iter()
.map(|vec| vec.into_iter().map(|val| val as f32).collect())
.collect();
In this example:
- Each value in the
f64vectors is explicitly cast tof32usingas f32. - The
mapfunction applies this conversion to every value in the embeddings.
Now, the resulting embeddings_f32 can be passed to functions expecting f32 values without errors.
Key Takeaways
- Rust Enforces Type Safety:
- Rust’s strict type system requires explicit conversions when types don’t match.
- When to Use
as f32:- Use
as f32to downcast values fromf64tof32when required by a library or for efficiency.
- Use
- Leverage Documentation and Compiler Feedback:
- Review API or library documentation to understand type expectations.
- Pay attention to compiler error messages, which often provide clear guidance.
Final Thoughts
Working with embeddings and numerical types in Rust might feel daunting at first due to the strict type system. However, this system ensures safety and correctness, especially in computationally intensive workflows like machine learning.
By understanding the requirements of your API and libraries, and utilizing tools like explicit casting, you can efficiently handle type mismatches and build robust Rust applications.

