l_system_fractals/errors.rs
1// src/errors.rs
2//
3// This file is part of l-system-fractals
4//
5// Copyright 2024 Christopher Phan
6//
7// See README.md in repository root directory for copyright/license info
8//
9// SPDX-License-Identifier: MIT OR Apache-2.0
10
11//! Provides an error type for the crate.
12use std::error::Error;
13use std::fmt;
14
15/// Combined error type for the crate.
16#[derive(Debug)]
17pub enum LSystemError {
18 /// Indicates division by zero attempted.
19 ///
20 /// # Example
21 ///
22 /// ```
23 /// use std::collections::HashMap;
24 ///
25 /// use l_system_fractals::rules::DrawRules;
26 ///
27 /// let dr = DrawRules::new_simple(
28 /// HashMap::from([('A', "A-A+A-A".into())]),
29 /// 1,
30 /// 0 // denominator of a fraction
31 /// );
32 ///
33 /// assert!(dr.is_err());
34 ///
35 /// let err_msg = format!("{:?}", dr);
36 /// assert!(err_msg.contains("DivideByZero"));
37 /// ```
38 DivideByZero,
39 /// Indicates a float that is NaN or ±∞.
40 ///
41 /// These do not make sense in the context of SVG coordinates.
42 ///
43 /// This error is raised by, e.g., [`crate::num_validity::err_if_invalid`].
44 ///
45 /// # Example
46 ///
47 /// ```
48 /// use l_system_fractals::num_validity::err_if_invalid;
49 ///
50 /// let x = err_if_invalid(f64::NAN);
51 ///
52 /// let err_msg = format!("{:?}", x);
53 /// assert!(err_msg.contains("InvalidFloat"));
54 /// ```
55 InvalidFloat,
56 /// Indicates that no bounding box could be computed in a context where it is required.
57 ///
58 /// This error is raised by, e.g., [`crate::paths::Path::bounding_box`].
59 ///
60 /// # Example
61 ///
62 /// ```
63 /// use l_system_fractals::paths::{Path, Point};
64 ///
65 /// let empty_vec: Vec<Point> = vec![];
66 /// let empty_path = Path::from(empty_vec);
67 /// let bb = empty_path.bounding_box();
68 ///
69 /// let err_msg = format!("{:?}", bb);
70 /// assert!(err_msg.contains("NoBoundingBox"));
71 /// ```
72 NoBoundingBox,
73 /// Indicates a file system error (e.g. incorrect file name).
74 FileSystemError(Box<dyn Error>),
75 /// Indicates a problem in the deserialization process (e.g. malformed JSON).
76 DeserializationError(Box<dyn Error>),
77}
78
79impl fmt::Display for LSystemError {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 match self {
82 Self::DivideByZero => write!(f, "divide by zero error"),
83 Self::InvalidFloat => write!(f, "float is NaN or +/-INF"),
84 Self::NoBoundingBox => write!(f, "no bounding box"),
85 Self::FileSystemError(e) => write!(f, "file system error: {}", e),
86 Self::DeserializationError(e) => write!(f, "deserialization error: {}", e),
87 }
88 }
89}
90
91impl Error for LSystemError {}