Skip to main content

noodles_vcf/io/writer/header/record/value/
string.rs

1use std::io::{self, Write};
2
3use crate::header::FileFormat;
4
5const VCF_4_3: FileFormat = FileFormat::new(4, 3);
6
7pub(crate) fn write_string<W>(writer: &mut W, file_format: FileFormat, s: &str) -> io::Result<()>
8where
9    W: Write,
10{
11    // ยง 1.4 "Meta-information lines" (2024-04-20): "An _unstructured_ meta-information line
12    // consists of [...] a _value_ (which may not be empty and must not start with a '<'
13    // character)..."
14    fn is_valid(s: &str) -> bool {
15        const LESS_THAN_SIGN: char = '<';
16        s.chars().next().is_some_and(|c| c != LESS_THAN_SIGN)
17    }
18
19    if file_format < VCF_4_3 || is_valid(s) {
20        writer.write_all(s.as_bytes())
21    } else {
22        Err(io::Error::new(
23            io::ErrorKind::InvalidInput,
24            "invalid unstructured header record value",
25        ))
26    }
27}
28
29#[cfg(test)]
30mod tests {
31    use super::*;
32
33    #[test]
34    fn test_write_string() -> io::Result<()> {
35        const VCF_4_2: FileFormat = FileFormat::new(4, 2);
36
37        let mut buf = Vec::new();
38
39        buf.clear();
40        write_string(&mut buf, VCF_4_3, "ndls")?;
41        assert_eq!(buf, b"ndls");
42
43        buf.clear();
44        assert!(matches!(
45            write_string(&mut buf, VCF_4_3, ""),
46            Err(e) if e.kind() == io::ErrorKind::InvalidInput
47        ));
48
49        buf.clear();
50        write_string(&mut buf, VCF_4_2, "<")?;
51        assert_eq!(buf, b"<");
52
53        buf.clear();
54        assert!(matches!(
55            write_string(&mut buf, VCF_4_3, "<"),
56            Err(e) if e.kind() == io::ErrorKind::InvalidInput
57        ));
58
59        Ok(())
60    }
61}