contree/common/
outcome.rs1use serde::{Deserialize, Serialize};
4use std::fmt;
5
6use crate::common::Statistics;
7use crate::data::DatasetError;
8use crate::tree::{Tree, TreeError};
9
10#[derive(Clone, Debug, PartialEq, Eq)]
12pub enum SearchError {
13 EmptyDataset,
15 NoFeatures,
17 UnpreparedDataset,
25 InvalidParameter { name: &'static str, reason: String },
27 Data(DatasetError),
29 Tree(TreeError),
32}
33
34impl fmt::Display for SearchError {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 match self {
37 SearchError::EmptyDataset => write!(f, "the dataset has no instances"),
38 SearchError::NoFeatures => write!(f, "the dataset has no features"),
39 SearchError::UnpreparedDataset => write!(
40 f,
41 "the dataset has not been sorted and indexed; build it with \
42 Dataset::from_rows or DataReader"
43 ),
44 SearchError::InvalidParameter { name, reason } => {
45 write!(f, "invalid {name}: {reason}")
46 }
47 SearchError::Data(err) => write!(f, "{err}"),
48 SearchError::Tree(err) => write!(f, "the search produced an invalid tree: {err}"),
49 }
50 }
51}
52
53impl std::error::Error for SearchError {}
54
55impl From<DatasetError> for SearchError {
56 fn from(err: DatasetError) -> Self {
57 SearchError::Data(err)
58 }
59}
60
61impl From<TreeError> for SearchError {
62 fn from(err: TreeError) -> Self {
63 SearchError::Tree(err)
64 }
65}
66
67#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
72#[serde(rename_all = "snake_case")]
73pub enum SearchStatus {
74 Optimal,
76 TimeLimit,
78 BudgetExhausted,
80 ErrorBoundReached,
83}
84
85impl SearchStatus {
86 pub fn is_optimal(self) -> bool {
88 matches!(self, SearchStatus::Optimal)
89 }
90}
91
92impl fmt::Display for SearchStatus {
93 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94 f.write_str(match self {
95 SearchStatus::Optimal => "optimal",
96 SearchStatus::TimeLimit => "time limit",
97 SearchStatus::BudgetExhausted => "budget exhausted",
98 SearchStatus::ErrorBoundReached => "error bound reached",
99 })
100 }
101}
102
103#[derive(Clone, Debug)]
105pub struct FitOutcome {
106 pub tree: Tree,
108 pub statistics: Statistics,
110 pub status: SearchStatus,
112}
113
114impl FitOutcome {
115 pub fn error(&self) -> usize {
117 self.statistics.error
118 }
119}