sus-impls 0.2.1

Non-conflicting implementations for optional fields
Documentation
use std::env;
use std::io::{self, StdoutLock, Write};

use sus_impls::Dependency;

fn print_slice<T: std::fmt::Display>(stdout: &mut StdoutLock, slice: &[T]) {
    for element in slice {
        stdout.write_fmt(format_args!("{element} ")).unwrap();
    }
    stdout.write_fmt(format_args!("\n")).unwrap();
}

fn main() -> Result<(), &'static str> {
    let help_message = "Usage: cargo run 'INPUT'";

    let mut args = env::args().skip(1);
    let input = args.next().ok_or(help_message)?;
    let expr: syn::Expr = syn::parse_str(&input).unwrap();

    let field_names = &[
        "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r",
        "s", "t", "u", "v", "w", "x", "y", "z",
    ];
    let impls = sus_impls::impls(&expr, field_names).unwrap();

    let last_non_generic_ind = impls.iter().fold(0, |acc, implementation| {
        let last_non_generic_ind = implementation
            .iter()
            .rposition(|dep| matches!(dep, Dependency::Set | Dependency::Unset))
            .unwrap();
        if acc < last_non_generic_ind {
            last_non_generic_ind
        } else {
            acc
        }
    });

    let print_until = last_non_generic_ind + 1;

    let mut stdout = io::stdout().lock();

    print_slice(&mut stdout, &field_names[..print_until]);

    for implementation in impls {
        print_slice(&mut stdout, &implementation[..print_until]);
    }

    Ok(())
}