1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//! Error types for the `dbgen` library.
#![allow(clippy::used_underscore_binding)]
use crate::{parser::Rule, span::S};
use std::{convert::Infallible, fmt, path::PathBuf};
use thiserror::Error as ThisError;
/// Errors produced by the `dbgen` library.
#[derive(ThisError, Debug)]
#[non_exhaustive]
pub enum Error {
/// Failed to parse template.
#[error("failed to parse template")]
ParseTemplate(#[from] pest::error::Error<Rule>),
/// Unknown SQL function.
#[error("unknown function")]
UnknownFunction,
/// Integer is too big.
#[error("integer '{0}' is too big")]
IntegerOverflow(
/// The string representation of the expression that produced the overflow.
String,
),
/// Not enough arguments provided to the SQL function.
#[error("not enough arguments")]
NotEnoughArguments,
/// Invalid regex.
#[error("invalid regex")]
InvalidRegex(#[from] rand_regex::Error),
/// Unknown regex flag.
#[error("unknown regex flag '{0}'")]
UnknownRegexFlag(
/// The regex flag.
char,
),
/// Invalid arguments.
#[error("{0}")]
InvalidArguments(
/// Cause of the error.
String,
),
/// The timestamp string is invalid
#[error("invalid timestamp")]
InvalidTimestampString(#[from] chrono::format::ParseError),
/// Cannot find parent table for derived table directive.
#[error("cannot find parent table {parent} to generate derived rows")]
UnknownParentTable {
/// Expected parent table name.
parent: String,
},
/// Derived table name does not match that of the derived table directive.
#[error("derived table name in the FOR EACH ROW and CREATE TABLE statements do not match ({for_each_row} vs {create_table})")]
DerivedTableNameMismatch {
/// The table name in the FOR EACH ROW statement
for_each_row: String,
/// The table name in the CREATE TABLE statement
create_table: String,
},
/// Unexpected value type.
#[error("cannot convert {value} into {expected}")]
UnexpectedValueType {
/// The expected value type.
expected: &'static str,
/// The actual value.
value: String,
},
/// Generic IO error.
#[error("failed to {action} at {path}")]
Io {
/// Action causing the error.
action: &'static str,
/// File path causing the I/O error.
path: PathBuf,
/// Source of error.
source: std::io::Error,
},
/// Invalid time zone file.
#[error("failed to parse time zone file ({time_zone})")]
InvalidTimeZone {
/// Time zone name.
time_zone: String,
/// Source of error.
source: tzfile::Error,
},
/// Failed to configure a Rayon thread pool.
#[cfg(feature = "cli")]
#[error("failed to configure thread pool")]
Rayon(#[from] rayon::ThreadPoolBuildError),
/// Cannot use `--table-name` when template contains multiple tables.
#[error("cannot use --table-name when template contains multiple tables")]
CannotUseTableNameForMultipleTables,
/// Unsupported CLI parameter.
#[error("unsupported {kind} {value}")]
UnsupportedCliParameter {
/// The parameter name.
kind: &'static str,
/// Value provided by user.
value: String,
},
/// Forced panic.
#[error("runtime panic: {message}")]
Panic {
/// The panic message.
message: String,
},
}
impl fmt::Display for S<Error> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}
impl std::error::Error for S<Error> {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.inner.source()
}
}
impl From<Infallible> for Error {
fn from(never: Infallible) -> Self {
match never {}
}
}
impl From<regex_syntax::Error> for Error {
fn from(e: regex_syntax::Error) -> Self {
Self::InvalidRegex(e.into())
}
}