sst 0.19.0

SST provides a sorted string table abstraction.
Documentation
//! Truncate a log file that has the final-partial-frame corruption case present.

use arrrg::CommandLine;
use arrrg_derive::CommandLine;

use sst::LogOptions;

#[derive(CommandLine, Debug, Default, Eq, PartialEq)]
struct LogTruncateFinalPartialFrameOptions {
    #[arrrg(flag, "Perform the truncation (default: log the offset).")]
    truncate: bool,
    #[arrrg(optional, "Truncate to this length (requires: --truncate).")]
    truncate_to: Option<u64>,
    #[arrrg(nested)]
    log: LogOptions,
}

fn main() {
    let (cmdline, args) = LogTruncateFinalPartialFrameOptions::from_command_line(
        "Usage: log-truncate-final-partial-frame [OPTIONS] <SST>",
    );
    if args.len() != 1 {
        eprintln!("specify exactly one sst");
        std::process::exit(1);
    }
    if let Some(offset) =
        sst::log::truncate_final_partial_frame(cmdline.log.clone(), &args[0]).unwrap()
    {
        if cmdline.truncate {
            if let Some(truncate_to) = cmdline.truncate_to {
                if offset != truncate_to || offset > i32::MAX as u64 {
                    eprintln!(
                        "not truncating: required offset={offset}, specified offset={truncate_to}"
                    );
                    std::process::exit(2);
                // SAFETY(rescrv):  libc call with valid pointer and try_into with check above.
                } else if unsafe {
                    libc::truncate(args[0].as_ptr() as *const i8, offset.try_into().unwrap())
                } < 0
                {
                    let err = std::io::Error::last_os_error();
                    eprintln!("truncate failed: {err:?}");
                    std::process::exit(3);
                }
            } else {
                eprintln!("not truncating: specify --truncate-to {offset} to truncate");
                std::process::exit(2);
            }
        } else {
            println!("truncate to {offset} bytes");
        }
    } else {
        println!("truncate cannot help");
    }
}