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 {}