Count characters, words, and lines in files (wc in rust)
InputFile doesn't appear to be a file — a better name might be Statistics.
usize is conventionally used for indexes and sizes instead of u32.
Don't take an argument by &amp;String.  Since the algorithm works for not only files but other streams of characters as well, consider taking a BufRead argument.
Reading the whole file into memory isn't efficient — an alternative is to use the utf8-chars crate to identify characters.
c as u8 != 0 is just c != '\0'.
It took me a while to figure out what spaced does — in_word might be a better name.
char::is_whitespace checks for all kinds of whitespace.
In main, Iterator::skip allows you to skip one argument without allocating a Vec.

Here's my version:
use {
    anyhow::Result,
    parse_display::Display,
    std::{
        env,
        fs::File,
        io::{BufRead, BufReader},
    },
    utf8_chars::BufReadCharsExt,
};

#[derive(Clone, Debug, Display)]
#[display(&quot;{characters} {words} {lines}&quot;)]
struct Stats {
    characters: usize,
    words: usize,
    lines: usize,
}

impl Stats {
    fn new&lt;R: BufRead&gt;(mut reader: R) -&gt; Result&lt;Self&gt; {
        let mut stats = Stats {
            characters: 0,
            words: 0,
            lines: 0,
        };
        let mut in_word = false;

        for c in reader.chars_raw() {
            let c = c?;

            if c != '\0' {
                stats.characters += 1;
            }

            if !c.is_whitespace() {
                in_word = true;
            } else if in_word {
                stats.words += 1;
                in_word = false;
            }

            if c == '\n' {
                stats.lines += 1;
            }
        }

        Ok(stats)
    }
}

fn main() -&gt; Result&lt;()&gt; {
    for path in env::args().skip(1) {
        let file = BufReader::new(File::open(&amp;path)?);
        let stats = Stats::new(file)?;
        println!(&quot;{} {}&quot;, stats, path);
    }

    Ok(())
}