1#![warn(
12 unknown_lints,
13 absolute_paths_not_starting_with_crate,
15 elided_lifetimes_in_paths,
16 explicit_outlives_requirements,
17 macro_use_extern_crate,
18 nonstandard_style, noop_method_call,
20 rust_2018_idioms,
21 single_use_lifetimes,
22 trivial_casts,
23 trivial_numeric_casts,
24 future_incompatible, rust_2021_compatibility, missing_debug_implementations,
29 unreachable_pub,
31 unsafe_code,
33 unsafe_op_in_unsafe_fn,
34 unused, )]
37#![deny(
38 exported_private_dependencies,
40 private_in_public,
41 anonymous_parameters,
43 bare_trait_objects,
44 ellipsis_inclusive_range_patterns,
45 deref_nullptr,
47 drop_bounds,
48 dyn_drop,
49)]
50
51use std::{
52 fmt::{Debug, Display},
53 hash::Hash,
54 str::FromStr,
55};
56
57pub trait Code<T>: Clone + Debug + Display + FromStr + Into<T> + PartialEq + Eq + Hash {
62 fn is_valid<S>(s: S) -> bool
63 where
64 S: AsRef<str>,
65 {
66 Self::from_str(s.as_ref()).is_ok()
67 }
68}
69
70pub trait FixedLengthCode {
71 fn fixed_length() -> usize;
72}
73
74pub trait VariableLengthCode {
75 fn min_length() -> usize;
76
77 fn max_length() -> usize;
78}
79
80#[macro_export]
85macro_rules! code_as_str {
86 ($type_name:ty, $inner:ident) => {
87 impl $type_name {
88 fn as_str(&self) -> &str {
89 &self.$inner
90 }
91 }
92 };
93 ($type_name:ty) => {
94 impl $type_name {
95 fn as_str(&self) -> &str {
96 &self.0
97 }
98 }
99 };
100}
101
102#[macro_export]
103macro_rules! code_impl {
104 ($type_name:ty, $id_field:ident, $ltime:lifetime $id_type_ref:ty, $id_type:ty, $from_fn:ident) => {
105 impl ::std::fmt::Display for $type_name {
106 fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
107 write!(f, "{}", self.as_ref())
108 }
109 }
110
111 impl ::std::convert::AsRef<$id_type_ref> for $type_name {
112 fn as_ref(&self) -> &$ltime $id_type_ref {
113 &self.$id_field()
114 }
115 }
116
117 impl ::std::ops::Deref for $type_name {
118 type Target = $id_type_ref;
119
120 fn deref(&self) -> &$ltime Self::Target {
121 &self.$id_field()
122 }
123 }
124
125 impl ::std::convert::From<$type_name> for $id_type {
126 fn from(v: $type_name) -> Self {
127 v.$id_field().$from_fn()
128 }
129 }
130
131 impl $crate::Code<$id_type> for $type_name {}
132 };
133 ($type_name:ty, $id_field:ident, $id_type_ref:ty, $id_type:ty, $from_fn:ident) => {
134 impl ::std::fmt::Display for $type_name {
135 fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
136 write!(f, "{}", self.as_ref())
137 }
138 }
139
140 impl ::std::convert::AsRef<$id_type_ref> for $type_name {
141 fn as_ref(&self) -> &$id_type_ref {
142 &self.$id_field()
143 }
144 }
145
146 impl ::std::ops::Deref for $type_name {
147 type Target = $id_type_ref;
148
149 fn deref(&self) -> &Self::Target {
150 &self.$id_field()
151 }
152 }
153
154 impl ::std::convert::From<$type_name> for $id_type {
155 fn from(v: $type_name) -> Self {
156 v.$id_field().$from_fn()
157 }
158 }
159
160 impl $crate::Code<$id_type> for $type_name {}
161 };
162 ($type_name:ty, $id_field:ident, $id_type:ty) => {
163 impl ::std::fmt::Display for $type_name {
164 fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
165 write!(f, "{}", self.$id_field())
166 }
167 }
168
169 impl ::std::convert::From<$type_name> for $id_type {
170 fn from(v: $type_name) -> Self {
171 v.$id_field()
172 }
173 }
174
175 impl $crate::Code<$id_type> for $type_name {}
176 };
177
178 ($type_name:ty, $id_field:ident) => {
179 code_impl!($type_name, $id_field, 'static str, String, to_string);
180 };
181
182 ($type_name:ty) => {
183 code_impl!($type_name, code, 'static str, String, to_string);
184 };
185}
186
187#[macro_export]
188macro_rules! fixed_length_code {
189 ($type_name:ty, $length:literal) => {
190 impl $crate::FixedLengthCode for $type_name {
191 fn fixed_length() -> usize {
192 $length
193 }
194 }
195 };
196}
197
198#[macro_export]
199macro_rules! variable_length_code {
200 ($type_name:ty, $min:literal, $max:literal) => {
201 impl $crate::VariableLengthCode for $type_name {
202 fn min_length() -> usize {
203 $min
204 }
205 fn max_length() -> usize {
206 $max
207 }
208 }
209 };
210}
211
212pub mod error;
225pub use error::CodeParseError;
226
227#[cfg(feature = "build")]
228#[macro_use]
229pub mod build;