Skip to main content

stern4rust/settings/
header_source.rs

1// Copyright 2025 Umberto Gotti <umberto.gotti@umbertogotti.dev>
2// Licensed under the MIT License
3// SPDX-License-Identifier: MIT
4
5use std::fs;
6use std::path::Path;
7
8use anyhow::Context;
9use anyhow::Result;
10
11// Reads the expected header off disk.
12//
13// Trailing blank lines are dropped so the file can end with a newline -- every
14// editor adds one -- without the rule then demanding a blank line at the top of
15// every source file. The same normalisation SourceFile applies is applied here,
16// so a header file saved with CRLF or a byte order mark still matches sources
17// that were not.
18pub struct HeaderSource;
19
20impl HeaderSource {
21    pub fn read(path: &Path) -> Result<Vec<String>> {
22        let contents = fs::read_to_string(path)
23            .with_context(|| format!("failed to read header file {}", path.display()))?;
24        Ok(Self::parse(&contents))
25    }
26
27    pub fn parse(contents: &str) -> Vec<String> {
28        let contents = contents.strip_prefix('\u{feff}').unwrap_or(contents);
29        let mut lines: Vec<String> = contents
30            .split('\n')
31            .map(|line| line.strip_suffix('\r').unwrap_or(line).to_string())
32            .collect();
33        while lines.last().is_some_and(|line| line.trim().is_empty()) {
34            lines.pop();
35        }
36        lines
37    }
38}