ittech/parser/
scan.rs

1use std::fmt::{self, Display};
2
3
4/// Impulse Tracker file types
5#[derive(Clone, Copy, Debug)]
6pub enum FileType {
7    /// Module file
8    ///
9    /// Contains all information to play a track instruments, samples, patterns, etc.
10    Module,
11
12    /// Instrument file
13    ///
14    /// Contains an instrument description and its samples.
15    Instrument,
16
17    /// Sample file
18    ///
19    /// Contains one audio sample and its looping and frequency parameters.
20    Sample,
21}
22
23/// Error returned by [`scan`](crate::parser::scan::scan) function if no magic number is recognized
24#[derive(Clone, Copy, Debug)]
25pub struct ScanError(());
26
27
28/// Guess what Impulse Tracker file type is in the input buffer
29///
30/// Checks magic numbers at the beginning of the buffer in order to estimate what file type the
31/// buffer contains. This method only does a trivial analysis and doesn't guarantee that a file is
32/// actually the type it reports, however it is guaranteed that a different file type than was
33/// reported canot be parsed.
34///
35/// In other words this function can return a false positive but never a false negative.
36pub fn scan(input: &[u8]) -> Result<FileType, ScanError> {
37    match input {
38        [b'I', b'M', b'P', b'M', ..] => Ok(FileType::Module),
39        [b'I', b'M', b'P', b'I', ..] => Ok(FileType::Instrument),
40        [b'I', b'M', b'P', b'S', ..] => Ok(FileType::Sample),
41        _ => Err(ScanError(())),
42    }
43}
44
45
46impl Display for ScanError {
47    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48        f.write_str("no Impulse Tracker magic number was recognized")
49    }
50}
51
52impl std::error::Error for ScanError {}