Skip to content

Into conversions

If you have members of type String, or PathBuf, and you need to set them to a hard-coded string literal, then you have to write .to_owned() or .to_string() or .into().

rust
use std::path::PathBuf;

#[derive(bon::Builder)]  
struct Example {         
    name: String,        
    description: String, 
    path: PathBuf,       
}                        

Example::builder()
    .name("Bon".to_owned())                      
    .description("Awesome crate 🐱".to_string()) 
    .path("/path/to/bon".into())                 
    .build();
rust
use std::path::PathBuf;

#[bon::builder]          
fn example(              
    name: String,        
    description: String, 
    path: PathBuf,       
) {}                     

example()
    .name("Bon".to_owned())                      
    .description("Awesome crate 🐱".to_string()) 
    .path("/path/to/bon".into())                 
    .call();
rust
use std::path::PathBuf;

struct Example;

#[bon::bon]
impl Example {
    #[builder]               
    fn example(              
        name: String,        
        description: String, 
        path: PathBuf,       
    ) {}                     
}

Example::example()
    .name("Bon".to_owned())                      
    .description("Awesome crate 🐱".to_string()) 
    .path("/path/to/bon".into())                 
    .call();

However, you can ask bon to generate setters that accept impl Into<T> to remove the need for manual conversion.

This can be configured with #[builder(into)] for a single member or with #[builder(on({type}, into))] for many members at once.

rust
use std::path::PathBuf;

// All setters for members of type `String` will accept `impl Into<String>`
#[derive(bon::Builder)]                                                     
#[builder(on(String, into))]                                                
struct Example {
    name: String,
    description: String,

    // The setter only for this member will accept `impl Into<PathBuf>`
    #[builder(into)]                                                       
    path: PathBuf,
}

Example::builder()
    .name("Bon") 
    .description("Awesome crate 🐱") 
    .path("/path/to/your/heart") 
    .build();
rust
use std::path::PathBuf;

// All setters for members of type `String` will accept `impl Into<String>`
#[bon::builder(on(String, into))]                                           
fn example(
    name: String,
    description: String,

    // The setter only for this member will accept `impl Into<PathBuf>`
    #[builder(into)]                                                       
    path: PathBuf,
) {}

example()
    .name("Bon") 
    .description("Awesome crate 🐱") 
    .path("/path/to/your/heart") 
    .call();
rust
use std::path::PathBuf;

struct Example;

#[bon::bon]
impl Example {
    // All setters for members of type `String` will accept `impl Into<String>`
    #[builder(on(String, into))]                                                
    fn example(
        name: String,
        description: String,

        // The setter only for this member will accept `impl Into<PathBuf>`
        #[builder(into)]                                                       
        path: PathBuf,
    ) {}
}

Example::example()
    .name("Bon") 
    .description("Awesome crate 🐱") 
    .path("/path/to/your/heart") 
    .call();

Into conversions don't always make sense, and you should be aware of their downsides as well. The article Into Conversions In-Depth provides recommendations on when it makes sense to use and to avoid Into conversions.