Skip to content

Commit f18c73e

Browse files
committed
Replace nested Options with Limit newtype
Signed-off-by: Keith Koskie <[email protected]>
1 parent 6dacb62 commit f18c73e

File tree

3 files changed

+74
-64
lines changed

3 files changed

+74
-64
lines changed

cryptoki/src/slot/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ mod slot_info;
1010
mod token_info;
1111

1212
pub use slot_info::SlotInfo;
13-
pub use token_info::TokenInfo;
13+
pub use token_info::{Limit, TokenInfo};
1414

1515
use crate::error::{Error, Result};
1616
use cryptoki_sys::CK_SLOT_ID;

cryptoki/src/slot/token_info.rs

Lines changed: 73 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
55
use crate::error::{Error, Result};
66
use crate::string_from_blank_padded;
7-
use crate::types::{convert_utc_time, maybe_unlimited};
8-
use crate::types::{MaybeUnavailable, UtcTime, Version};
7+
use crate::types::convert_utc_time;
8+
use crate::types::{UtcTime, Version};
99
use bitflags::bitflags;
1010
use cryptoki_sys::*;
1111
use std::convert::TryFrom;
@@ -36,6 +36,17 @@ bitflags! {
3636
}
3737
}
3838

39+
#[derive(Debug, Clone, Copy)]
40+
/// A limiting value for the token that may or may not take an explicit value
41+
pub enum Limit {
42+
/// There is an explict value for this limit
43+
Max(u64),
44+
/// The token does not provide information about this limit
45+
Unavailable,
46+
/// The limit is "effectively infinite" and may be treated as such
47+
Infinite,
48+
}
49+
3950
/// Information about a token
4051
#[derive(Debug, Clone)]
4152
pub struct TokenInfo {
@@ -44,9 +55,9 @@ pub struct TokenInfo {
4455
model: String, // 16
4556
serial_number: String, // 16
4657
flags: TokenInfoFlags,
47-
max_session_count: Option<Option<u64>>,
58+
max_session_count: Limit,
4859
session_count: Option<u64>,
49-
max_rw_session_count: Option<Option<u64>>,
60+
max_rw_session_count: Limit,
5061
rw_session_count: Option<u64>,
5162
max_pin_len: usize,
5263
min_pin_len: usize,
@@ -58,6 +69,53 @@ pub struct TokenInfo {
5869
firmware_version: Version,
5970
utc_time: Option<UtcTime>,
6071
}
72+
trait MaybeUnavailable: Sized {
73+
fn maybe_unavailable(value: CK_ULONG) -> Option<Self>;
74+
}
75+
76+
impl MaybeUnavailable for usize {
77+
fn maybe_unavailable(value: CK_ULONG) -> Option<usize> {
78+
if value == CK_UNAVAILABLE_INFORMATION {
79+
None
80+
} else {
81+
Some(value as usize)
82+
}
83+
}
84+
}
85+
86+
impl MaybeUnavailable for u64 {
87+
fn maybe_unavailable(value: CK_ULONG) -> Option<u64> {
88+
if value == CK_UNAVAILABLE_INFORMATION {
89+
None
90+
} else {
91+
// Must have cast for when ulong is 32 bits
92+
// Must have lint suppression when ulong is 64 bits
93+
#[allow(trivial_numeric_casts)]
94+
Some(value as u64)
95+
}
96+
}
97+
}
98+
99+
/// Flattens both `Infinite` and `Unavailable` to `None`,
100+
impl From<Limit> for Option<u64> {
101+
fn from(limit: Limit) -> Self {
102+
match limit {
103+
Limit::Unavailable | Limit::Infinite => None,
104+
Limit::Max(n) => Some(n),
105+
}
106+
}
107+
}
108+
109+
fn maybe_unlimited(value: CK_ULONG) -> Limit {
110+
match value {
111+
CK_UNAVAILABLE_INFORMATION => Limit::Unavailable,
112+
CK_EFFECTIVELY_INFINITE => Limit::Infinite,
113+
// Must have cast for when ulong is 32 bits
114+
// Must have lint suppression when ulong is 64 bits
115+
#[allow(trivial_numeric_casts)]
116+
_ => Limit::Max(value as u64),
117+
}
118+
}
61119

62120
impl TokenInfo {
63121
/// An application-defined label, assigned during token initialization
@@ -280,11 +338,8 @@ impl TokenInfo {
280338
}
281339

282340
/// The maximum number of sessions that can be opened with the token at one
283-
/// time by a single application
284-
/// If `None`, this information was unavailable.
285-
/// If `Some(None)` there is no maximum, meaning the value is effectively infinite
286-
/// If `Some(Some(n))` the maximum number of sessions is `n`
287-
pub fn max_session_count(&self) -> Option<Option<u64>> {
341+
/// time by a single application.
342+
pub fn max_session_count(&self) -> Limit {
288343
self.max_session_count
289344
}
290345

@@ -295,11 +350,8 @@ impl TokenInfo {
295350
}
296351

297352
/// The maximum number of read/write sessions that can be opened with the
298-
/// token at one time by a single application
299-
/// If `None`, this information was unavailable.
300-
/// If `Some(None)` there is no maximum, meaning the value is effectively infinite
301-
/// If `Some(Some(n))` the maximum number of read/write sessions is `n`
302-
pub fn max_rw_session_count(&self) -> Option<Option<u64>> {
353+
/// token at one time by a single application.
354+
pub fn max_rw_session_count(&self) -> Limit {
303355
self.max_rw_session_count
304356
}
305357

@@ -406,7 +458,7 @@ impl TryFrom<CK_TOKEN_INFO> for TokenInfo {
406458

407459
#[cfg(test)]
408460
mod test {
409-
use super::{TokenInfo, TokenInfoFlags};
461+
use super::{Limit, TokenInfo, TokenInfoFlags};
410462
use crate::types::{UtcTime, Version};
411463

412464
#[test]
@@ -431,9 +483,9 @@ SO_PIN_TO_BE_CHANGED | ERROR_STATE";
431483
model: String::from("Token Model"),
432484
serial_number: String::from("Serial Number"),
433485
flags: TokenInfoFlags::empty(),
434-
max_session_count: Some(Some(100)), // max == 100
435-
session_count: None, // unavailable
436-
max_rw_session_count: Some(None), // max == infinite
486+
max_session_count: Limit::Max(100), // max == 100
487+
session_count: None, // unavailable
488+
max_rw_session_count: Limit::Infinite, // max == infinite
437489
rw_session_count: Some(1),
438490
max_pin_len: 16,
439491
min_pin_len: 4,
@@ -458,15 +510,11 @@ SO_PIN_TO_BE_CHANGED | ERROR_STATE";
458510
model: "Token Model",
459511
serial_number: "Serial Number",
460512
flags: (empty),
461-
max_session_count: Some(
462-
Some(
463-
100,
464-
),
513+
max_session_count: Max(
514+
100,
465515
),
466516
session_count: None,
467-
max_rw_session_count: Some(
468-
None,
469-
),
517+
max_rw_session_count: Infinite,
470518
rw_session_count: Some(
471519
1,
472520
),

cryptoki/src/types.rs

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -140,44 +140,6 @@ impl std::fmt::Display for Ulong {
140140
}
141141
}
142142

143-
pub(crate) trait MaybeUnavailable: Sized {
144-
fn maybe_unavailable(value: CK_ULONG) -> Option<Self>;
145-
}
146-
147-
impl MaybeUnavailable for usize {
148-
fn maybe_unavailable(value: CK_ULONG) -> Option<usize> {
149-
if value == CK_UNAVAILABLE_INFORMATION {
150-
None
151-
} else {
152-
Some(value as usize)
153-
}
154-
}
155-
}
156-
157-
impl MaybeUnavailable for u64 {
158-
fn maybe_unavailable(value: CK_ULONG) -> Option<u64> {
159-
if value == CK_UNAVAILABLE_INFORMATION {
160-
None
161-
} else {
162-
// Must have cast for when ulong is 32 bits
163-
// Must have lint suppression when ulong is 64 bits
164-
#[allow(trivial_numeric_casts)]
165-
Some(value as u64)
166-
}
167-
}
168-
}
169-
170-
pub(crate) fn maybe_unlimited(value: CK_ULONG) -> Option<Option<u64>> {
171-
match value {
172-
CK_UNAVAILABLE_INFORMATION => None,
173-
CK_EFFECTIVELY_INFINITE => Some(None),
174-
// Must have cast for when ulong is 32 bits
175-
// Must have lint suppression when ulong is 64 bits
176-
#[allow(trivial_numeric_casts)]
177-
_ => Some(Some(value as u64)),
178-
}
179-
}
180-
181143
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
182144
/// Represents a version
183145
pub struct Version {

0 commit comments

Comments
 (0)