• 0 Posts
  • 11 Comments
Joined 5 months ago
cake
Cake day: January 25th, 2026

help-circle

  • Cell doesn’t disable memory safety, though? It comes with additional restrictions such as being unable to share between threads (statically enforced) obviously, it’s not an unsafe feature. You also can’t read from it unless your type can be bitwise copied, etc.

    Interior mutability is mostly for making immutable interfaces that for some reason or another benefit from storing a bit of mutable state, such as for lazy evaluation. It’s also used for cross thread communication in some cases since you have to use shared (immutable) references to share things between threads.

    It requires a lot of nigh-illegible boilerplate code to even compile

    this is the entire source code for an app that performs a rather complex function, note the absence of boilerplate

    from https://codeberg.org/Mycellf/wordjoin

    use std::{
        fs::File,
        io::{self, BufRead, BufReader, Read, Write},
        path::PathBuf,
    };
    
    use clap::{Parser, ValueEnum};
    use icu_segmenter::{
        LineSegmenter, LineSegmenterBorrowed,
        options::{LineBreakOptions, LineBreakStrictness, LineBreakWordOption},
    };
    
    /// Insert utf-8 word joiners (U+2060) to prevent text from wrapping outside of whitespace characters.
    #[derive(Parser)]
    struct Args {
        /// Format and concatenate each file in stead of stdin
        file_paths: Vec<PathBuf>,
    
        /// Read stdin by line instead of all at once
        /// (sometimes worse for interactive use; files are always read by line)
        #[clap(short = 'l', long)]
        by_line: bool,
    
        /// See https://drafts.csswg.org/css-text-3/#line-break-property
        #[clap(short, long, default_value = "strict")]
        strictness: LineBreakStrictnessValues,
        /// See https://drafts.csswg.org/css-text-3/#word-break-property
        #[clap(short, long, default_value = "normal")]
        word_option: LineBreakWordOptionValues,
    
        /// Print this app's GNU GPL-3.0 license
        #[arg(short = 'L', long)]
        license: bool,
    
        /// Print this app's source code
        #[arg(short = 'S', long)]
        source: bool,
    }
    
    const WORD_JOINER: char = '\u{2060}';
    
    fn main() -> io::Result<()> {
        let args = Args::parse();
    
        if args.source || args.license {
            if args.source {
                println!(
                    "Cargo.toml:\n{config}\n\nsrc/main.rs:\n{source}\n\nREADME.md:\n{readme}",
                    config = include_str!("../Cargo.toml"),
                    source = include_str!("main.rs"),
                    readme = include_str!("../README.md"),
                );
            }
    
            if args.license {
                println!("LICENSE:\n{}", include_str!("../LICENSE"));
            }
    
            return Ok(());
        }
    
        let mut options = LineBreakOptions::default();
        options.strictness = Some(args.strictness.into());
        options.word_option = Some(args.word_option.into());
    
        let segmenter = LineSegmenter::new_auto(options);
    
        let mut stdout = io::stdout().lock();
    
        if args.file_paths.is_empty() {
            let stdin = io::stdin();
    
            if args.by_line {
                join_text_by_lines(stdout, stdin, segmenter)?;
            } else {
                join_text_by_all(stdout, stdin, segmenter)?;
            }
        } else {
            for path in args.file_paths {
                let file = File::open(path)?;
    
                join_text_by_lines(&mut stdout, file, segmenter)?;
            }
        }
    
        Ok(())
    }
    
    fn join_text_by_lines(
        mut writer: impl Write,
        text: impl Read,
        segmenter: LineSegmenterBorrowed,
    ) -> io::Result<()> {
        for line in BufReader::new(text).lines() {
            let line = line?;
    
            join_text(&mut writer, &line, segmenter)?;
            writeln!(&mut writer)?;
        }
    
        Ok(())
    }
    
    fn join_text_by_all(
        writer: impl Write,
        mut text: impl Read,
        segmenter: LineSegmenterBorrowed,
    ) -> io::Result<()> {
        let mut input = String::new();
        text.read_to_string(&mut input)?;
    
        join_text(writer, &input, segmenter)?;
    
        Ok(())
    }
    
    fn join_text(
        mut writer: impl Write,
        text: &str,
        segmenter: LineSegmenterBorrowed,
    ) -> io::Result<()> {
        let mut segments = segmenter.segment_str(text).peekable();
    
        while let (Some(start), Some(&end)) = (segments.next(), segments.peek()) {
            let segment = &text[start..end];
    
            write!(writer, "{segment}")?;
    
            if end < text.len()
                && segment
                    .chars()
                    .next_back()
                    .is_some_and(|end| !end.is_whitespace())
            {
                write!(writer, "{WORD_JOINER}")?;
            }
        }
    
        Ok(())
    }
    
    #[derive(Clone, ValueEnum)]
    enum LineBreakStrictnessValues {
        Loose,
        Normal,
        Strict,
        Anywhere,
    }
    
    impl From<LineBreakStrictnessValues> for LineBreakStrictness {
        fn from(value: LineBreakStrictnessValues) -> Self {
            match value {
                LineBreakStrictnessValues::Loose => LineBreakStrictness::Loose,
                LineBreakStrictnessValues::Normal => LineBreakStrictness::Normal,
                LineBreakStrictnessValues::Strict => LineBreakStrictness::Strict,
                LineBreakStrictnessValues::Anywhere => LineBreakStrictness::Anywhere,
            }
        }
    }
    
    #[derive(Clone, ValueEnum)]
    enum LineBreakWordOptionValues {
        Normal,
        BreakAll,
        KeepAll,
    }
    
    impl From<LineBreakWordOptionValues> for LineBreakWordOption {
        fn from(value: LineBreakWordOptionValues) -> Self {
            match value {
                LineBreakWordOptionValues::Normal => LineBreakWordOption::Normal,
                LineBreakWordOptionValues::BreakAll => LineBreakWordOption::BreakAll,
                LineBreakWordOptionValues::KeepAll => LineBreakWordOption::KeepAll,
            }
        }
    }
    






  • What do you mean by “abstract away”, and what about it is exclusive to headers?

    Eg most languages have something like a trait or interface wherein you can put a list of definitions (optionally with a default aka “inline” implementation) which are then actually implemented elsewhere. This is considered useful by everyone because it allows multiple implementations to be associated with 1 name. They are generally not desired in cases where only 1 implementation will ever be written.

    AFAIK the only use case where headers accomplish the same is if they’re treated as documentation for an API that could be implemented by any library.

    Admittedly certain programming styles benefit immensely from headers, despite the drawbacks to “design as you go” programming.