off_rs/lib.rs
1#![warn(clippy::pedantic)]
2
3//! A simple `.off` file parser.
4//!
5//! # Usage
6//!
7//! ```rust
8//! let off_string = r#"
9//!OFF
10//!3 1
11//!1.0 0.0 0.0
12//!0.0 1.0 0.0
13//!0.0 0.0 1.0
14//!4 0 1 2 3 255 0 0 # red
15//!"#;
16//!
17//!let mesh = off_rs::parse(
18//! off_string,
19//! Default::default() // optional ParserOptions
20//!);
21//! ```
22
23pub mod geometry;
24pub mod parser;
25
26use crate::geometry::mesh::Mesh;
27use crate::parser::options::Options;
28use crate::parser::Parser;
29use std::fs::File;
30use std::io::{self, Read};
31use std::path::Path;
32
33/// Contains errors that occur during parsing.
34#[derive(Debug)]
35pub enum Error {
36 /// An IO error occurred while reading the file.
37 IOError(io::Error),
38 /// An error occurred during parsing the `off` data.
39 ParserError(crate::parser::error::Error),
40}
41
42impl std::error::Error for Error {}
43
44impl std::fmt::Display for Error {
45 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
46 match self {
47 Error::IOError(e) => write!(f, "IO Error: {}", e),
48 Error::ParserError(e) => write!(f, "Parser Error: {}", e),
49 }
50 }
51}
52
53impl From<io::Error> for Error {
54 fn from(e: io::Error) -> Self {
55 Error::IOError(e)
56 }
57}
58
59impl From<crate::parser::error::Error> for Error {
60 fn from(e: crate::parser::error::Error) -> Self {
61 Error::ParserError(e)
62 }
63}
64
65/// This result may contain the parsed [`crate::geometry::mesh::Mesh`] or the [`self::Result`] that occurred.
66pub type Result<D = Mesh> = std::result::Result<D, Error>;
67
68/// Parse a [`crate::geometry::mesh::Mesh`] from a [`std::path::Path`] pointing to an `.off` file.
69///
70/// # Errors
71///
72/// Will return `self::Error` if an error occurs while reading the file or parsing the `off` data.
73pub fn from_path<P: AsRef<Path>>(path: P, options: Options) -> Result {
74 let mut file = File::open(path).map_err(Error::IOError)?;
75
76 let mut string = String::new();
77 match file.read_to_string(&mut string) {
78 Ok(_) => {}
79 Err(inner) => return Err(Error::IOError(inner)),
80 };
81
82 parse(&string, options)
83}
84
85/// Directly parse a [`crate::geometry::mesh::Mesh`] from an `off` string.
86///
87/// # Examples
88///
89/// ```rust
90/// let off_string = r#"
91///OFF
92///3 1
93///1.0 0.0 0.0
94///0.0 1.0 0.0
95///0.0 0.0 1.0
96///4 0 1 2 3 1.0 0.0 0.0 1.0 # red
97///"#;
98///
99/// let mesh = off_rs::parse(
100/// off_string,
101/// Default::default(), // optional ParserOptions
102/// );
103///
104/// println!("{:#?}", mesh);
105/// ```
106///
107/// # Errors
108///
109/// Will return `self::Error` if an error occurs while parsing the `off` data.
110pub fn parse(string: &str, options: Options) -> Result {
111 Parser::new(&string, options).parse()
112}