~matthiasbeyer/imag

e21d4db54380e051b6f92e670ca2dac8ae2e35a7 — Matthias Beyer 2 years ago f4c2771 + 605b982
Merge branch 'clippy' into master
M .travis.yml => .travis.yml +12 -0
@@ 55,6 55,18 @@ matrix:
          script:
            - cargo build --all --all-features -j 1  || exit 1
            - cargo test  --all --all-features -j 1  || exit 1
        - language: rust
          rust: stable
          name: clippy
          cache:
            directories:
              - /home/travis/.cargo
          before_cache:
            - rm -rf /home/travis/.cargo/registry
          install:
            - rustup component add clippy
          script:
            - cargo clippy --all --all-targets


addons:

M bin/core/imag-ids/src/main.rs => bin/core/imag-ids/src/main.rs +2 -2
@@ 79,10 79,10 @@ fn main() {
                ::std::process::exit(1);
            });
        Box::new(ids.into_iter().map(Ok))
            as Box<Iterator<Item = Result<StoreId, _>>>
            as Box<dyn Iterator<Item = Result<StoreId, _>>>
    } else {
        Box::new(rt.store().entries().map_err_trace_exit_unwrap())
            as Box<Iterator<Item = Result<StoreId, _>>>
            as Box<dyn Iterator<Item = Result<StoreId, _>>>
    }
    .trace_unwrap_exit()
    .map(|id| if print_storepath {

M bin/domain/imag-contact/src/create.rs => bin/domain/imag-contact/src/create.rs +3 -3
@@ 76,7 76,7 @@ mod test {
    }
}

fn ask_continue(inputstream: &mut Read, outputstream: &mut Write) -> bool {
fn ask_continue(inputstream: &mut dyn Read, outputstream: &mut dyn Write) -> bool {
    ::libimaginteraction::ask::ask_bool("Edit tempfile", Some(true), inputstream, outputstream)
        .map_err_trace_exit_unwrap()
}


@@ 97,7 97,7 @@ pub fn create(rt: &Runtime) {
        .map_err_trace_exit_unwrap();
    // TODO: Refactor the above to libimagutil or libimagrt?

    let (mut dest, location, uuid) : (Box<Write>, Option<PathBuf>, String) = {
    let (mut dest, location, uuid) : (Box<dyn Write>, Option<PathBuf>, String) = {
        if let Some(mut fl) = scmd.value_of("file-location").map(PathBuf::from) {
            let uuid = if fl.is_file() {
                error!("File does exist, cannot create/override");


@@ 232,7 232,7 @@ pub fn create(rt: &Runtime) {
    info!("Ready");
}

fn parse_toml_into_vcard(output: &mut Write, input: &mut Read, toml: Value, uuid: String) -> Option<Vcard> {
fn parse_toml_into_vcard(output: &mut dyn Write, input: &mut dyn Read, toml: Value, uuid: String) -> Option<Vcard> {
    let mut vcard = VcardBuilder::new().with_uid(uuid);

    { // parse name

M bin/domain/imag-contact/src/edit.rs => bin/domain/imag-contact/src/edit.rs +1 -1
@@ 113,7 113,7 @@ fn edit_contact<'a>(rt: &Runtime, contact: &FileLockEntry<'a>, ref_config: &RefC
        .map(|_| ())
}

fn ask_continue(inputstream: &mut Read, outputstream: &mut Write) -> bool {
fn ask_continue(inputstream: &mut dyn Read, outputstream: &mut dyn Write) -> bool {
    ::libimaginteraction::ask::ask_bool("Edit vcard", Some(true), inputstream, outputstream)
        .map_err_trace_exit_unwrap()
}

M bin/domain/imag-log/src/main.rs => bin/domain/imag-log/src/main.rs +1 -1
@@ 266,7 266,7 @@ fn get_log_text(rt: &Runtime) -> String {
        })
}

fn do_write_to<'a>(sink: &mut Write, id: DiaryId, entry: &FileLockEntry<'a>, do_remove_newlines: bool) -> RResult<(), ExitCode> {
fn do_write_to<'a>(sink: &mut dyn Write, id: DiaryId, entry: &FileLockEntry<'a>, do_remove_newlines: bool) -> RResult<(), ExitCode> {
    let text = if do_remove_newlines {
        entry.get_content().trim_end().replace("\n", "")
    } else {

M lib/core/libimagstore/src/file_abstraction/fs.rs => lib/core/libimagstore/src/file_abstraction/fs.rs +3 -3
@@ 136,7 136,7 @@ impl FileAbstraction for FSFileAbstraction {
        Ok(path.is_file())
    }

    fn new_instance(&self, p: PathBuf) -> Box<FileAbstractionInstance> {
    fn new_instance(&self, p: PathBuf) -> Box<dyn FileAbstractionInstance> {
        Box::new(FSFileAbstractionInstance(p))
    }



@@ 156,7 156,7 @@ impl FileAbstraction for FSFileAbstraction {
    fn pathes_recursively<'a>(&self,
                          basepath: PathBuf,
                          storepath: &'a PathBuf,
                          backend: Arc<FileAbstraction>)
                          backend: Arc<dyn FileAbstraction>)
        -> Result<PathIterator<'a>>
    {
        trace!("Building PathIterator object");


@@ 170,7 170,7 @@ pub struct WalkDirPathIterBuilder {
}

impl PathIterBuilder for WalkDirPathIterBuilder {
    fn build_iter(&self) -> Box<Iterator<Item = Result<PathBuf>>> {
    fn build_iter(&self) -> Box<dyn Iterator<Item = Result<PathBuf>>> {
        trace!("Building iterator for {}", self.basepath.display());
        Box::new(WalkDir::new(self.basepath.clone())
            .min_depth(1)

M lib/core/libimagstore/src/file_abstraction/inmemory.rs => lib/core/libimagstore/src/file_abstraction/inmemory.rs +3 -3
@@ 164,7 164,7 @@ impl FileAbstraction for InMemoryFileAbstraction {
        self.exists(pb)
    }

    fn new_instance(&self, p: PathBuf) -> Box<FileAbstractionInstance> {
    fn new_instance(&self, p: PathBuf) -> Box<dyn FileAbstractionInstance> {
        Box::new(InMemoryFileAbstractionInstance::new(self.backend().clone(), p))
    }



@@ 187,7 187,7 @@ impl FileAbstraction for InMemoryFileAbstraction {
        Ok(())
    }

    fn pathes_recursively<'a>(&self, _basepath: PathBuf, storepath: &'a PathBuf, backend: Arc<FileAbstraction>) -> Result<PathIterator<'a>> {
    fn pathes_recursively<'a>(&self, _basepath: PathBuf, storepath: &'a PathBuf, backend: Arc<dyn FileAbstraction>) -> Result<PathIterator<'a>> {
        trace!("Building PathIterator object (inmemory implementation)");
        let keys : Vec<PathBuf> = self
            .backend()


@@ 207,7 207,7 @@ impl FileAbstraction for InMemoryFileAbstraction {
pub struct InMemPathIterBuilder(Vec<PathBuf>);

impl PathIterBuilder for InMemPathIterBuilder {
    fn build_iter(&self) -> Box<Iterator<Item = Result<PathBuf>>> {
    fn build_iter(&self) -> Box<dyn Iterator<Item = Result<PathBuf>>> {
        Box::new(self.0.clone().into_iter().map(Ok))
    }


M lib/core/libimagstore/src/file_abstraction/iter.rs => lib/core/libimagstore/src/file_abstraction/iter.rs +7 -7
@@ 28,7 28,7 @@ use crate::file_abstraction::FileAbstraction;

/// See documentation for PathIterator
pub(crate) trait PathIterBuilder : Debug {
    fn build_iter(&self) -> Box<Iterator<Item = Result<PathBuf>>>;
    fn build_iter(&self) -> Box<dyn Iterator<Item = Result<PathBuf>>>;
    fn in_collection(&mut self, c: &str) -> Result<()>;
}



@@ 47,17 47,17 @@ pub(crate) trait PathIterBuilder : Debug {
/// This means quite a few allocations down the road, as the PathIterator itself is not generic, but
/// this seems to be the best way to implement this.
pub(crate) struct PathIterator<'a> {
    iter_builder: Box<PathIterBuilder>,
    iter:         Box<Iterator<Item = Result<PathBuf>>>,
    iter_builder: Box<dyn PathIterBuilder>,
    iter:         Box<dyn Iterator<Item = Result<PathBuf>>>,
    storepath:    &'a PathBuf,
    backend:      Arc<FileAbstraction>,
    backend:      Arc<dyn FileAbstraction>,
}

impl<'a> PathIterator<'a> {

    pub fn new(iter_builder: Box<PathIterBuilder>,
    pub fn new(iter_builder: Box<dyn PathIterBuilder>,
               storepath: &'a PathBuf,
               backend: Arc<FileAbstraction>)
               backend: Arc<dyn FileAbstraction>)
        -> PathIterator<'a>
    {
        trace!("Generating iterator object with PathIterBuilder: {:?}", iter_builder);


@@ 81,7 81,7 @@ impl<'a> PathIterator<'a> {
    ///
    /// Revisit whether this can be done in a cleaner way. See commit message for why this is
    /// needed.
    pub(crate) fn into_inner(self) -> Box<Iterator<Item = Result<PathBuf>>> {
    pub(crate) fn into_inner(self) -> Box<dyn Iterator<Item = Result<PathBuf>>> {
        self.iter
    }


M lib/core/libimagstore/src/file_abstraction/mod.rs => lib/core/libimagstore/src/file_abstraction/mod.rs +2 -2
@@ 43,12 43,12 @@ pub(crate) trait FileAbstraction : Debug {
    fn exists(&self, _: &PathBuf) -> Result<bool>;
    fn is_file(&self, _: &PathBuf) -> Result<bool>;

    fn new_instance(&self, p: PathBuf) -> Box<FileAbstractionInstance>;
    fn new_instance(&self, p: PathBuf) -> Box<dyn FileAbstractionInstance>;

    fn drain(&self) -> Result<Drain>;
    fn fill<'a>(&'a mut self, d: Drain) -> Result<()>;

    fn pathes_recursively<'a>(&self, basepath: PathBuf, storepath: &'a PathBuf, backend: Arc<FileAbstraction>) -> Result<PathIterator<'a>>;
    fn pathes_recursively<'a>(&self, basepath: PathBuf, storepath: &'a PathBuf, backend: Arc<dyn FileAbstraction>) -> Result<PathIterator<'a>>;
}

/// An abstraction trait over actions on files

M lib/core/libimagstore/src/iter.rs => lib/core/libimagstore/src/iter.rs +2 -2
@@ 33,11 33,11 @@ macro_rules! mk_iterator_mod {
            use crate::store::Store;
            use failure::Fallible as Result;

            pub struct $itername<'a>(Box<Iterator<Item = Result<StoreId>> + 'a>, &'a Store);
            pub struct $itername<'a>(Box<dyn Iterator<Item = Result<StoreId>> + 'a>, &'a Store);

            impl<'a> $itername<'a>
            {
                pub fn new(inner: Box<Iterator<Item = Result<StoreId>> + 'a>, store: &'a Store) -> Self {
                pub fn new(inner: Box<dyn Iterator<Item = Result<StoreId>> + 'a>, store: &'a Store) -> Self {
                    $itername(inner, store)
                }
            }

M lib/core/libimagstore/src/store.rs => lib/core/libimagstore/src/store.rs +5 -5
@@ 62,13 62,13 @@ enum StoreEntryStatus {
struct StoreEntry {
    id: StoreId,
    store_base: PathBuf, // small sacrefice over lifetimes on the Store type
    file: Box<FileAbstractionInstance>,
    file: Box<dyn FileAbstractionInstance>,
    status: StoreEntryStatus,
}

impl StoreEntry {

    fn new(store_base: PathBuf, id: StoreId, backend: &Arc<FileAbstraction>) -> Result<StoreEntry> {
    fn new(store_base: PathBuf, id: StoreId, backend: &Arc<dyn FileAbstraction>) -> Result<StoreEntry> {
        let pb = id.clone().with_base(&store_base).into_pathbuf()?;

        #[cfg(feature = "fs-lock")]


@@ 144,7 144,7 @@ pub struct Store {
    /// The backend to use
    ///
    /// This provides the filesystem-operation functions (or pretends to)
    backend: Arc<FileAbstraction>,
    backend: Arc<dyn FileAbstraction>,
}

impl Store {


@@ 186,7 186,7 @@ impl Store {
    /// Do not use directly, only for testing purposes.
    pub(crate) fn new_with_backend(location: PathBuf,
                        store_config: &Option<Value>,
                        backend: Arc<FileAbstraction>) -> Result<Store> {
                        backend: Arc<dyn FileAbstraction>) -> Result<Store> {
        use crate::configuration::*;

        debug!("Building new Store object");


@@ 792,7 792,7 @@ impl Entry {

    /// See `Entry::from_str()`, as this function is used internally. This is just a wrapper for
    /// convenience.
    pub fn from_reader<S: IntoStoreId>(loc: S, file: &mut Read) -> Result<Entry> {
    pub fn from_reader<S: IntoStoreId>(loc: S, file: &mut dyn Read) -> Result<Entry> {
        let text = {
            let mut s = String::new();
            file.read_to_string(&mut s).context(EM::IO)?;

M lib/core/libimagstore/src/storeid.rs => lib/core/libimagstore/src/storeid.rs +3 -3
@@ 248,7 248,7 @@ macro_rules! module_entry_path_mod {
}

pub struct StoreIdIterator {
    iter: Box<Iterator<Item = Result<StoreId>>>,
    iter: Box<dyn Iterator<Item = Result<StoreId>>>,
}

impl Debug for StoreIdIterator {


@@ 261,7 261,7 @@ impl Debug for StoreIdIterator {

impl StoreIdIterator {

    pub fn new(iter: Box<Iterator<Item = Result<StoreId>>>) -> StoreIdIterator {
    pub fn new(iter: Box<dyn Iterator<Item = Result<StoreId>>>) -> StoreIdIterator {
        StoreIdIterator { iter }
    }



@@ 300,7 300,7 @@ impl<'a> Iterator for StoreIdIteratorWithStore<'a> {

impl<'a> StoreIdIteratorWithStore<'a> {

    pub fn new(iter: Box<Iterator<Item = Result<StoreId>>>, store: &'a Store) -> Self {
    pub fn new(iter: Box<dyn Iterator<Item = Result<StoreId>>>, store: &'a Store) -> Self {
        StoreIdIteratorWithStore(StoreIdIterator::new(iter), store)
    }


M lib/domain/libimagtimetrack/src/iter/tag.rs => lib/domain/libimagtimetrack/src/iter/tag.rs +2 -2
@@ 27,10 27,10 @@ use crate::iter::storeid::TagStoreIdIter;

use libimagentrytag::tag::is_tag_str;

pub struct TagIter(Box<Iterator<Item = String>>);
pub struct TagIter(Box<dyn Iterator<Item = String>>);

impl TagIter {
    pub fn new(i: Box<Iterator<Item = String>>) -> TagIter {
    pub fn new(i: Box<dyn Iterator<Item = String>>) -> TagIter {
        TagIter(i)
    }


M lib/entry/libimagentrycategory/src/entry.rs => lib/entry/libimagentrycategory/src/entry.rs +2 -2
@@ 36,7 36,7 @@ pub trait EntryCategory {

    fn set_category(&mut self, s: &str) -> Result<()>;

    fn set_category_checked(&mut self, register: &CategoryStore, s: &str) -> Result<()>;
    fn set_category_checked(&mut self, register: &dyn CategoryStore, s: &str) -> Result<()>;

    fn get_category(&self) -> Result<String>;



@@ 61,7 61,7 @@ impl EntryCategory for Entry {
    /// Check whether a category exists before setting it.
    ///
    /// This function should be used by default over EntryCategory::set_category()!
    fn set_category_checked(&mut self, register: &CategoryStore, s: &str) -> Result<()> {
    fn set_category_checked(&mut self, register: &dyn CategoryStore, s: &str) -> Result<()> {
        trace!("Setting category '{}' checked", s);
        let mut category = register
            .get_category_by_name(s)?

M lib/etc/libimaginteraction/src/ask.rs => lib/etc/libimaginteraction/src/ask.rs +3 -3
@@ 32,11 32,11 @@ use failure::Fallible as Result;

/// Ask the user for a Yes/No answer. Optionally provide a default value. If none is provided, this
/// keeps loop{}ing
pub fn ask_bool(s: &str, default: Option<bool>, input: &mut Read, output: &mut Write) -> Result<bool> {
pub fn ask_bool(s: &str, default: Option<bool>, input: &mut dyn Read, output: &mut dyn Write) -> Result<bool> {
    ask_bool_(s, default, &mut BufReader::new(input), output)
}

fn ask_bool_<R: BufRead>(s: &str, default: Option<bool>, input: &mut R, output: &mut Write) -> Result<bool> {
fn ask_bool_<R: BufRead>(s: &str, default: Option<bool>, input: &mut R, output: &mut dyn Write) -> Result<bool> {
    lazy_static! {
        static ref R_YES: Regex = Regex::new(r"^[Yy](\n?)$").unwrap();
        static ref R_NO: Regex  = Regex::new(r"^[Nn](\n?)$").unwrap();


@@ 68,7 68,7 @@ fn ask_bool_<R: BufRead>(s: &str, default: Option<bool>, input: &mut R, output: 
/// trailing questionmark.
///
/// The `nl` parameter can be used to configure whether a newline character should be printed
pub fn ask_question(question: &str, nl: bool, output: &mut Write) -> Result<()> {
pub fn ask_question(question: &str, nl: bool, output: &mut dyn Write) -> Result<()> {
    if nl {
        writeln!(output, "[imag]: {}?", Yellow.paint(question))
    } else {

M lib/etc/libimaginteraction/src/format.rs => lib/etc/libimaginteraction/src/format.rs +16 -16
@@ 27,7 27,7 @@ use ansi_term::Style;
pub struct ColorizeBlackHelper;

impl HelperDef for ColorizeBlackHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut Output) -> Result<(), RenderError> {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut dyn Output) -> Result<(), RenderError> {
        colorize(Colour::Black, h, out)
    }
}


@@ 36,7 36,7 @@ impl HelperDef for ColorizeBlackHelper {
pub struct ColorizeBlueHelper;

impl HelperDef for ColorizeBlueHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut Output) -> Result<(), RenderError> {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut dyn Output) -> Result<(), RenderError> {
        colorize(Colour::Blue, h, out)
    }
}


@@ 45,7 45,7 @@ impl HelperDef for ColorizeBlueHelper {
pub struct ColorizeCyanHelper;

impl HelperDef for ColorizeCyanHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut Output) -> Result<(), RenderError> {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut dyn Output) -> Result<(), RenderError> {
        colorize(Colour::Cyan, h, out)
    }
}


@@ 54,7 54,7 @@ impl HelperDef for ColorizeCyanHelper {
pub struct ColorizeGreenHelper;

impl HelperDef for ColorizeGreenHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut Output) -> Result<(), RenderError> {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut dyn Output) -> Result<(), RenderError> {
        colorize(Colour::Green, h, out)
    }
}


@@ 63,7 63,7 @@ impl HelperDef for ColorizeGreenHelper {
pub struct ColorizePurpleHelper;

impl HelperDef for ColorizePurpleHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut Output) -> Result<(), RenderError> {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut dyn Output) -> Result<(), RenderError> {
        colorize(Colour::Purple, h, out)
    }
}


@@ 72,7 72,7 @@ impl HelperDef for ColorizePurpleHelper {
pub struct ColorizeRedHelper;

impl HelperDef for ColorizeRedHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut Output) -> Result<(), RenderError> {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut dyn Output) -> Result<(), RenderError> {
        colorize(Colour::Red, h, out)
    }
}


@@ 81,7 81,7 @@ impl HelperDef for ColorizeRedHelper {
pub struct ColorizeWhiteHelper;

impl HelperDef for ColorizeWhiteHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut Output) -> Result<(), RenderError> {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut dyn Output) -> Result<(), RenderError> {
        colorize(Colour::White, h, out)
    }
}


@@ 90,13 90,13 @@ impl HelperDef for ColorizeWhiteHelper {
pub struct ColorizeYellowHelper;

impl HelperDef for ColorizeYellowHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut Output) -> Result<(), RenderError> {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut dyn Output) -> Result<(), RenderError> {
        colorize(Colour::Yellow, h, out)
    }
}

#[inline]
fn colorize(color: Colour, h: &Helper, output: &mut Output) -> Result<(), RenderError> {
fn colorize(color: Colour, h: &Helper, output: &mut dyn Output) -> Result<(), RenderError> {
    let p = h.param(0).ok_or(RenderError::new("Too few arguments"))?;

    output.write(&format!("{}", color.paint(p.value().render())))?;


@@ 107,7 107,7 @@ fn colorize(color: Colour, h: &Helper, output: &mut Output) -> Result<(), Render
pub struct UnderlineHelper;

impl HelperDef for UnderlineHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut Output) -> Result<(), RenderError> {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut dyn Output) -> Result<(), RenderError> {
            let p = h.param(0).ok_or(RenderError::new("Too few arguments"))?;
            let s = Style::new().underline();
            out.write(&format!("{}", s.paint(p.value().render())))?;


@@ 119,7 119,7 @@ impl HelperDef for UnderlineHelper {
pub struct BoldHelper;

impl HelperDef for BoldHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut Output) -> Result<(), RenderError> {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut dyn Output) -> Result<(), RenderError> {
            let p = h.param(0).ok_or(RenderError::new("Too few arguments"))?;
            let s = Style::new().bold();
            out.write(&format!("{}", s.paint(p.value().render())))?;


@@ 131,7 131,7 @@ impl HelperDef for BoldHelper {
pub struct BlinkHelper;

impl HelperDef for BlinkHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut Output) -> Result<(), RenderError> {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut dyn Output) -> Result<(), RenderError> {
            let p = h.param(0).ok_or(RenderError::new("Too few arguments"))?;
            let s = Style::new().blink();
            out.write(&format!("{}", s.paint(p.value().render())))?;


@@ 143,7 143,7 @@ impl HelperDef for BlinkHelper {
pub struct StrikethroughHelper;

impl HelperDef for StrikethroughHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut Output) -> Result<(), RenderError> {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut dyn Output) -> Result<(), RenderError> {
            let p = h.param(0).ok_or(RenderError::new("Too few arguments"))?;
            let s = Style::new().strikethrough();
            out.write(&format!("{}", s.paint(p.value().render())))?;


@@ 162,7 162,7 @@ fn param_to_number(idx: usize, h: &Helper) -> Result<u64, RenderError> {
pub struct LeftPadHelper;

impl HelperDef for LeftPadHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut Output) -> Result<(), RenderError> {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut dyn Output) -> Result<(), RenderError> {
        let count = param_to_number(0, h)? as usize;
        let text = h.param(1).ok_or(RenderError::new("Too few arguments"))?;
        let text = format!("{:>width$}", text.value().render(), width = count);


@@ 175,7 175,7 @@ impl HelperDef for LeftPadHelper {
pub struct RightPadHelper;

impl HelperDef for RightPadHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut Output) -> Result<(), RenderError> {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut dyn Output) -> Result<(), RenderError> {
        let count = param_to_number(0, h)? as usize;
        let text = h.param(1).ok_or(RenderError::new("Too few arguments"))?;
        let text = format!("{:width$}", text.value().render(), width = count);


@@ 188,7 188,7 @@ impl HelperDef for RightPadHelper {
pub struct AbbrevHelper;

impl HelperDef for AbbrevHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut Output) -> Result<(), RenderError> {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _r: &'reg Registry, _ctx: &'rc Context, _rc: &mut RenderContext<'reg>, out: &mut dyn Output) -> Result<(), RenderError> {
        let count = param_to_number(0, h)? as usize;
        let text = h.param(1).ok_or(RenderError::new("Too few arguments"))?.value().render();
        out.write(&text.chars().take(count).collect::<String>())?;