blend/parsers/
mod.rs

1pub mod blend;
2pub mod dna;
3pub mod field;
4pub mod primitive;
5
6use nom::{
7    error::{ErrorKind, ParseError},
8    IResult,
9};
10use std::io;
11
12type Result<'a, T> = IResult<&'a [u8], T, BlendParseError>;
13
14/// Size of a pointer on the machine used to create the .blend file.
15#[derive(Debug, Copy, Clone)]
16pub enum PointerSize {
17    Bits32,
18    Bits64,
19}
20
21impl PointerSize {
22    /// Returns the pointer size in bytes.
23    pub fn bytes_num(self) -> usize {
24        match self {
25            PointerSize::Bits32 => 4,
26            PointerSize::Bits64 => 8,
27        }
28    }
29}
30
31/// Endianness of the machine used to create the .blend file.
32#[derive(Debug, Copy, Clone)]
33pub enum Endianness {
34    Little,
35    Big,
36}
37
38/// Errors that can happen during the initial parsing of the .blend file.
39/// Most errors are simply `NomError` but a few of them are specific either
40/// for better error reporting or due to custom logic.
41#[derive(Debug)]
42pub enum BlendParseError {
43    NomError {
44        kind: ErrorKind,
45        other: Option<Box<BlendParseError>>,
46    },
47    IoError(io::Error),
48    
49    /// Returned when the file is incomplete.
50    NotEnoughData,
51
52    /// The known block codes are `b"REND"`, `b"TEST"`, `b"GLOB"`, `b"DATA"` and any two-digit code
53    /// like `b"OB\0\0"` for objects. Anything different from that returns `UnknownBlockCode`
54    UnknownBlockCode,
55
56    /// Principal blocks are assumed to never be lists even though it is possible. This is done
57    /// to simplify the API. No version of a blend file was found where this isn't true.
58    UnsupportedCountOnPrincipalBlock,
59
60    /// This error happens if a block has a memory address equal to `0`. This should be impossible
61    /// as `0` represents a null pointer.
62    InvalidMemoryAddress,
63
64    /// Returned when the DNA block is not found at the end of the blend file.
65    NoDnaBlockFound,
66
67    /// Returned when the file doesn't start with `b"BLENDER"`. The assumption is that the file
68    /// is a gzip compressed blend file, but this isn't actually tested for.
69    CompressedFileNotSupported,
70}
71
72impl ParseError<&[u8]> for BlendParseError {
73    fn from_error_kind(_input: &[u8], kind: ErrorKind) -> Self {
74        BlendParseError::NomError { kind, other: None }
75    }
76
77    fn append(_input: &[u8], kind: ErrorKind, other: Self) -> Self {
78        BlendParseError::NomError {
79            kind,
80            other: Some(Box::new(other)),
81        }
82    }
83}