#[derive(Debug)]
pub struct SearchQueryBuilder(String);
impl SearchQueryBuilder {
pub fn new() -> Self {
SearchQueryBuilder(String::new())
}
pub fn add_tag(&mut self, tag: &str) -> &mut Self {
self.0.reserve(tag.len());
for c in tag.chars() {
if c == ' ' {
self.0.push('_');
} else {
self.0.push(c);
}
}
self.0.push(' ');
self
}
pub fn add_tag_iter<I, S>(&mut self, iter: I) -> &mut Self
where
I: Iterator<Item = S>,
S: AsRef<str>,
{
for s in iter {
self.add_tag(s.as_ref());
}
self
}
pub fn take_query_string(&mut self) -> String {
if self.0.ends_with(' ') {
self.0.pop();
}
std::mem::take(&mut self.0)
}
pub fn into_query_string(mut self) -> String {
if self.0.ends_with(' ') {
self.0.pop();
}
self.0
}
}
impl From<SearchQueryBuilder> for String {
fn from(search_query_builder: SearchQueryBuilder) -> Self {
search_query_builder.into_query_string()
}
}
impl Default for SearchQueryBuilder {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn build_search_query_works() {
let query = SearchQueryBuilder::new()
.add_tag("deep space waifu")
.take_query_string();
assert_eq!(query, "deep_space_waifu");
}
}