Skip to content

Commit a4f7f94

Browse files
committed
Turn str_check function into a macro and put it in id_macros
No longer pass as an argument to str_id macro. I think str_check was defined originally as a function because we were novice macro users. That function was always passed for construction of the type, it was used exclusively for that purpose, and it seems unlikely that it will need to be varied. Have str_check just evaluate to an Option<String> rather than a Result. Promote the Option to the error in str_id. Removes duplication and isolates the use of the DmResult type to two places. Signed-off-by: mulhern <amulhern@redhat.com>
1 parent 7e8718b commit a4f7f94

2 files changed

Lines changed: 37 additions & 28 deletions

File tree

src/id_macros.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,35 @@
55
// A module to contain functionality used for generating DM ids which
66
// are restricted in length and format by devicemapper.
77

8+
// Evaluates to an error string if the value does not match the requirements.
9+
macro_rules! str_check {
10+
($value:expr, $max_allowed_chars:expr) => {{
11+
let value = $value;
12+
let max_allowed_chars = $max_allowed_chars;
13+
if !value.is_ascii() {
14+
Some(format!("value {} has some non-ascii characters", value))
15+
} else {
16+
let num_chars = value.len();
17+
if num_chars == 0 {
18+
Some("value has zero characters".into())
19+
} else if num_chars > max_allowed_chars {
20+
Some(format!(
21+
"value {} has {} chars which is greater than maximum allowed {}",
22+
value, num_chars, max_allowed_chars
23+
))
24+
} else {
25+
None
26+
}
27+
}
28+
}};
29+
}
30+
831
/// Define borrowed and owned versions of string types that guarantee
932
/// conformance to DM restrictions, such as maximum length.
1033
// This implementation follows the example of Path/PathBuf as closely as
1134
// possible.
1235
macro_rules! str_id {
13-
($B:ident, $O:ident, $MAX:ident, $check:ident) => {
36+
($B:ident, $O:ident, $MAX:ident) => {
1437
/// The borrowed version of the DM identifier.
1538
#[derive(Debug, PartialEq, Eq, Hash)]
1639
pub struct $B {
@@ -27,7 +50,11 @@ macro_rules! str_id {
2750
/// Create a new borrowed identifier from a `&str`.
2851
#[allow(clippy::new_ret_no_self)]
2952
pub fn new(value: &str) -> DmResult<&$B> {
30-
$check(value, $MAX - 1)?;
53+
if let Some(err_msg) = str_check!(value, $MAX - 1) {
54+
return Err(DmError::Core(
55+
ErrorKind::InvalidArgument(err_msg.into()).into(),
56+
));
57+
}
3158
Ok(unsafe { &*(value as *const str as *const $B) })
3259
}
3360

@@ -56,7 +83,11 @@ macro_rules! str_id {
5683
/// Construct a new owned identifier.
5784
#[allow(clippy::new_ret_no_self)]
5885
pub fn new(value: String) -> DmResult<$O> {
59-
$check(&value, $MAX - 1)?;
86+
if let Some(err_msg) = str_check!(&value, $MAX - 1) {
87+
return Err(DmError::Core(
88+
ErrorKind::InvalidArgument(err_msg.into()).into(),
89+
));
90+
}
6091
Ok($O { inner: value })
6192
}
6293
}

src/types.rs

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -62,36 +62,14 @@ impl Sectors {
6262
}
6363
}
6464

65-
/// Returns an error if value is unsuitable.
66-
fn str_check(value: &str, max_allowed_chars: usize) -> DmResult<()> {
67-
if !value.is_ascii() {
68-
let err_msg = format!("value {} has some non-ascii characters", value);
69-
return Err(DmError::Core(ErrorKind::InvalidArgument(err_msg).into()));
70-
}
71-
let num_chars = value.len();
72-
if num_chars == 0 {
73-
return Err(DmError::Core(
74-
ErrorKind::InvalidArgument("value has zero characters".into()).into(),
75-
));
76-
}
77-
if num_chars > max_allowed_chars {
78-
let err_msg = format!(
79-
"value {} has {} chars which is greater than maximum allowed {}",
80-
value, num_chars, max_allowed_chars
81-
);
82-
return Err(DmError::Core(ErrorKind::InvalidArgument(err_msg).into()));
83-
}
84-
Ok(())
85-
}
86-
8765
/// A devicemapper name. Really just a string, but also the argument type of
8866
/// DevId::Name. Used in function arguments to indicate that the function
8967
/// takes only a name, not a devicemapper uuid.
90-
str_id!(DmName, DmNameBuf, DM_NAME_LEN, str_check);
68+
str_id!(DmName, DmNameBuf, DM_NAME_LEN);
9169

9270
/// A devicemapper uuid. A devicemapper uuid has a devicemapper-specific
9371
/// format.
94-
str_id!(DmUuid, DmUuidBuf, DM_UUID_LEN, str_check);
72+
str_id!(DmUuid, DmUuidBuf, DM_UUID_LEN);
9573

9674
/// Used as a parameter for functions that take either a Device name
9775
/// or a Device UUID.
@@ -115,7 +93,7 @@ impl<'a> fmt::Display for DevId<'a> {
11593
/// Number of bytes in Struct_dm_target_spec::target_type field.
11694
const DM_TARGET_TYPE_LEN: usize = 16;
11795

118-
str_id!(TargetType, TargetTypeBuf, DM_TARGET_TYPE_LEN, str_check);
96+
str_id!(TargetType, TargetTypeBuf, DM_TARGET_TYPE_LEN);
11997

12098
#[cfg(test)]
12199
mod tests {

0 commit comments

Comments
 (0)