Skip to content

Consuming build but by mut setters? #321

Description

@VorpalBlade

It seems #[builder(pattern = "owned")] changes the behaviour of both the build function as well as the setters. I would like to decouple that:

  • I have a builder that I build in a loop parsing a section + key/value file. For this is is more convenient to have &mut setters. Additionally I'd like to stick the builder in an Option to more easily handle the case of the first section / empty file. Consuming setters are quite unwieldy in that case.
  • Some of the fields are quite heavy Vecs and I won't reuse the builder for the next section (each section is a clean slate). As such I would like a consuming build to avoid clones.

The pattern looks something like this in pseudo-rust:

let mut results = vec![];
let mut builder = None
let mut buffer = String::new();

while input.read_line(&mut buffer)? > 0 {
    let line = buffer.trim();
    // Handle new section (which also has the name of the section in it)
    if let Some(stripped) = line.strip_prefix("EntryThatIndicatesNewSection: ") {
        if let Some(inner) = builder {
            results.push(inner.build());
        }
        builder = Some(Builder::new());
        builder.as_mut().unwrap().name(stripped)
    } else if let Some(stripped) = line.strip_prefix("OtherEntry: ") {
        // Handle other fields, some are mandatory, some are optional (have defaults on builder)
        builder.as_mut().unwrap().other_entry(stripped);
    } else if let Some(stripped) = line.strip_prefix("AnotherEntry: ") {
        // ...
    }
    buffer.clear();
}

// Handle final entry
if let Some(inner) = builder {
    results.push(inner.build());
}

This is leaving out proper error handling etc for clarity, but it is there in the real thing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions