I'm creating a method to format data out of an iterator. To allow chaining, I'm trying to provide it as new method of Iterator through generics :
trait ToSeparatedString {
fn to_separated_string(self, line_prefix: &str, separator: &str) -> String;
}
impl<T, I> ToSeparatedString for I
where
T: Display,
I: Iterator<Item = T> + Clone,
{
fn to_separated_string(self, line_prefix: &str, separator: &str) -> String {
let len = self.clone().count();
self.enumerate()
.map(|(i, line)| if i < len - 1 {
(line, separator)
} else {
(line, "")
})
.fold::<String, _>("".to_owned(), |acc, (line, line_end)| {
format!("{}{}{}{}", acc, line_prefix, line, line_end)
})
}
}
Then I'm using it here :
#[derive(Debug)]
pub struct TransactionDocumentBuilder<'a> {
/// Currency Id.
pub currency: &'a str,
/// Document timestamp.
pub blockstamp: Blockstamp,
/// Transaction locktime (in seconds ?)
pub locktime: u64,
/// List of issuers.
pub issuers: Vec<ed25519::PublicKey>,
/// List of inputs.
pub inputs: Vec<Input>,
/// List of outputs.
pub outputs: Vec<Output>,
/// Transaction comment.
pub comment: &'a str,
}
impl<'a> DocumentBuilder<TransactionDocument> for TransactionDocumentBuilder<'a> {
fn build_with_signature(self, signature: ed25519::Signature) -> TransactionDocument {
TransactionDocument {
document: GenericDocumentBuilder::new(10, "Transaction", self.currency)
.with("Blockstamp", &self.blockstamp.to_string())
.with("Locktime", &self.locktime.to_string())
.with("Issuers", &self.issuers.iter().to_separated_string("", "\n"))
.with("Inputs", &self.inputs.iter()
.map(|input| input.source)
.to_separated_string("", " "))
// Iterate through each input unlocks
.with("Unlocks", &self.inputs.iter()
.enumerate()
.map(|(i, input)| {
input.unlocks.iter().to_separated_string(&i.to_string(), "\n")
})
.to_separated_string("", "\n")
)
// more fields
.build_with_signature(signature),
};
unimplemented!()
}
fn build_and_sign(self, _private_key: &ed25519::PrivateKey) -> TransactionDocument {
unimplemented!()
}
}
It's works when I'm using it after an .iter() but not after a .map(), and says it's not implemented. But std::slice::Iter and std::iter::Map implements Iterator<Item = T> + Clone, so where is the problem ?
Thank you beforehand for you help.