diff --git a/Cargo.lock b/Cargo.lock index dcf57df1..edbb0078 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1035,6 +1035,7 @@ dependencies = [ "pem", "pkcs8", "rasn", + "scursor", "tokio", "tokio-mock-io", "tokio-rustls", @@ -1169,6 +1170,11 @@ dependencies = [ "untrusted", ] +[[package]] +name = "scursor" +version = "0.1.0" +source = "git+https://github.com/stepfunc/scursor.git?tag=0.1.0#4d876ce9d08cb42a22b039c847b04728ddc88fd5" + [[package]] name = "semver" version = "0.11.0" diff --git a/dep_config.json b/dep_config.json index 0298c8ef..b3fe7ccb 100644 --- a/dep_config.json +++ b/dep_config.json @@ -39,6 +39,9 @@ }, "rodbus-ffi-java": { "url": "https://github.com/stepfunc/rodbus" + }, + "scursor": { + "url": "https://github.com/stepfunc/scursor" } }, "third_party": { diff --git a/rodbus/Cargo.toml b/rodbus/Cargo.toml index 382fd634..8d9ac5aa 100644 --- a/rodbus/Cargo.toml +++ b/rodbus/Cargo.toml @@ -11,6 +11,7 @@ readme = "../README.md" [dependencies] crc = "2.0" +scursor = { git = "https://github.com/stepfunc/scursor.git", tag="0.1.0" } tokio = { version = "1", features = ["net", "sync", "io-util", "io-std", "time", "rt", "rt-multi-thread", "macros"] } tracing = "0.1" diff --git a/rodbus/src/client/message.rs b/rodbus/src/client/message.rs index 08f08f16..77b23aaa 100644 --- a/rodbus/src/client/message.rs +++ b/rodbus/src/client/message.rs @@ -10,9 +10,10 @@ use crate::client::requests::read_bits::ReadBits; use crate::client::requests::read_registers::ReadRegisters; use crate::client::requests::write_multiple::MultipleWriteRequest; use crate::client::requests::write_single::SingleWrite; -use crate::common::cursor::{ReadCursor, WriteCursor}; use crate::common::traits::Serialize; use crate::types::{Indexed, UnitId}; + +use scursor::{ReadCursor, WriteCursor}; use std::time::Duration; pub(crate) enum Setting { @@ -97,7 +98,7 @@ impl Request { RequestError::Exception(exception) } else { tracing::warn!("invalid modbus exception"); - RequestError::BadResponse(AduParseError::TrailingBytes(cursor.len())) + RequestError::BadResponse(AduParseError::TrailingBytes(cursor.remaining())) } } Err(err) => err.into(), diff --git a/rodbus/src/client/requests/read_bits.rs b/rodbus/src/client/requests/read_bits.rs index 93e5460b..84b64575 100644 --- a/rodbus/src/client/requests/read_bits.rs +++ b/rodbus/src/client/requests/read_bits.rs @@ -1,4 +1,3 @@ -use crate::common::cursor::{ReadCursor, WriteCursor}; use crate::common::function::FunctionCode; use crate::common::traits::Serialize; use crate::decode::AppDecodeLevel; @@ -6,6 +5,8 @@ use crate::error::RequestError; use crate::types::{AddressRange, BitIterator, BitIteratorDisplay, ReadBitsRange}; use crate::Indexed; +use scursor::{ReadCursor, WriteCursor}; + pub(crate) trait BitsCallback: FnOnce(Result) + Send + Sync + 'static { diff --git a/rodbus/src/client/requests/read_registers.rs b/rodbus/src/client/requests/read_registers.rs index fb677db9..8ba7e7ff 100644 --- a/rodbus/src/client/requests/read_registers.rs +++ b/rodbus/src/client/requests/read_registers.rs @@ -1,4 +1,3 @@ -use crate::common::cursor::{ReadCursor, WriteCursor}; use crate::common::function::FunctionCode; use crate::common::traits::Serialize; use crate::decode::AppDecodeLevel; @@ -7,6 +6,8 @@ use crate::types::{ AddressRange, Indexed, ReadRegistersRange, RegisterIterator, RegisterIteratorDisplay, }; +use scursor::{ReadCursor, WriteCursor}; + pub(crate) trait RegistersCallback: FnOnce(Result) + Send + Sync + 'static { diff --git a/rodbus/src/client/requests/write_multiple.rs b/rodbus/src/client/requests/write_multiple.rs index ca2c26f0..29593daa 100644 --- a/rodbus/src/client/requests/write_multiple.rs +++ b/rodbus/src/client/requests/write_multiple.rs @@ -1,5 +1,4 @@ use crate::client::message::Promise; -use crate::common::cursor::{ReadCursor, WriteCursor}; use crate::common::function::FunctionCode; use crate::common::traits::{Parse, Serialize}; use crate::decode::AppDecodeLevel; @@ -7,6 +6,7 @@ use crate::error::RequestError; use crate::error::{AduParseError, InvalidRequest}; use crate::types::{AddressRange, Indexed}; +use scursor::{ReadCursor, WriteCursor}; use std::convert::TryFrom; /// Collection of values and starting address diff --git a/rodbus/src/client/requests/write_single.rs b/rodbus/src/client/requests/write_single.rs index 9bf3ab18..d4b8a945 100644 --- a/rodbus/src/client/requests/write_single.rs +++ b/rodbus/src/client/requests/write_single.rs @@ -1,13 +1,14 @@ use std::fmt::Display; use crate::client::message::Promise; -use crate::common::cursor::{ReadCursor, WriteCursor}; use crate::common::function::FunctionCode; use crate::decode::AppDecodeLevel; use crate::error::AduParseError; use crate::error::RequestError; use crate::types::{coil_from_u16, coil_to_u16, Indexed}; +use scursor::{ReadCursor, WriteCursor}; + pub(crate) trait SingleWriteOperation: Sized + PartialEq { fn serialize(&self, cursor: &mut WriteCursor) -> Result<(), RequestError>; fn parse(cursor: &mut ReadCursor) -> Result; diff --git a/rodbus/src/common/buffer.rs b/rodbus/src/common/buffer.rs index fa1dbceb..8aeb255f 100644 --- a/rodbus/src/common/buffer.rs +++ b/rodbus/src/common/buffer.rs @@ -1,8 +1,5 @@ use crate::common::phys::PhysLayer; -#[cfg(feature = "no-panic")] -use no_panic::no_panic; - use crate::error::InternalError; use crate::PhysDecodeLevel; @@ -21,17 +18,14 @@ impl ReadBuffer { } } - #[cfg_attr(feature = "no-panic", no_panic)] pub(crate) fn len(&self) -> usize { self.end - self.begin } - #[cfg_attr(feature = "no-panic", no_panic)] pub(crate) fn is_empty(&self) -> bool { self.begin == self.end } - #[cfg_attr(feature = "no-panic", no_panic)] pub(crate) fn read(&mut self, count: usize) -> Result<&[u8], InternalError> { if self.len() < count { return Err(InternalError::InsufficientBytesForRead(count, self.len())); @@ -46,7 +40,6 @@ impl ReadBuffer { } } - #[cfg_attr(feature = "no-panic", no_panic)] pub(crate) fn read_u8(&mut self) -> Result { if self.is_empty() { return Err(InternalError::InsufficientBytesForRead(1, 0)); @@ -60,7 +53,6 @@ impl ReadBuffer { } } - #[cfg_attr(feature = "no-panic", no_panic)] #[cfg(feature = "serial")] pub(crate) fn peek_at(&mut self, idx: usize) -> Result { let len = self.len(); @@ -73,14 +65,12 @@ impl ReadBuffer { .ok_or(InternalError::InsufficientBytesForRead(idx + 1, len)) } - #[cfg_attr(feature = "no-panic", no_panic)] pub(crate) fn read_u16_be(&mut self) -> Result { let b1 = self.read_u8()? as u16; let b2 = self.read_u8()? as u16; Ok((b1 << 8) | b2) } - #[cfg_attr(feature = "no-panic", no_panic)] #[cfg(feature = "serial")] pub(crate) fn read_u16_le(&mut self) -> Result { let b1 = self.read_u8()? as u16; diff --git a/rodbus/src/common/cursor.rs b/rodbus/src/common/cursor.rs deleted file mode 100644 index 93a830dc..00000000 --- a/rodbus/src/common/cursor.rs +++ /dev/null @@ -1,157 +0,0 @@ -use crate::error::{AduParseError, InternalError}; -use std::ops::Range; - -#[cfg(feature = "no-panic")] -use no_panic::no_panic; - -/// custom read-only cursor -pub(crate) struct ReadCursor<'a> { - src: &'a [u8], -} - -/// custom write cursor -pub(crate) struct WriteCursor<'a> { - dest: &'a mut [u8], - pos: usize, -} - -impl<'a> std::ops::Index> for WriteCursor<'a> { - type Output = [u8]; - - fn index(&self, index: Range) -> &Self::Output { - &self.dest[index] - } -} - -impl<'a> ReadCursor<'a> { - #[cfg_attr(feature = "no-panic", no_panic)] - pub(crate) fn new(src: &'a [u8]) -> ReadCursor { - ReadCursor { src } - } - - #[cfg_attr(feature = "no-panic", no_panic)] - pub(crate) fn len(&self) -> usize { - self.src.len() - } - - #[cfg_attr(feature = "no-panic", no_panic)] - pub(crate) fn is_empty(&self) -> bool { - self.src.is_empty() - } - - #[cfg_attr(feature = "no-panic", no_panic)] - pub(crate) fn expect_empty(&self) -> Result<(), AduParseError> { - if self.is_empty() { - Ok(()) - } else { - Err(AduParseError::TrailingBytes(self.len())) - } - } - - #[cfg_attr(feature = "no-panic", no_panic)] - pub(crate) fn read_u8(&mut self) -> Result { - match self.src.split_first() { - Some((first, rest)) => { - self.src = rest; - Ok(*first) - } - None => Err(AduParseError::InsufficientBytes), - } - } - - #[cfg_attr(feature = "no-panic", no_panic)] - pub(crate) fn read_u16_be(&mut self) -> Result { - let high = self.read_u8()?; - let low = self.read_u8()?; - Ok((high as u16) << 8 | (low as u16)) - } - - #[cfg_attr(feature = "no-panic", no_panic)] - pub(crate) fn read_bytes(&mut self, count: usize) -> Result<&'a [u8], AduParseError> { - match (self.src.get(0..count), self.src.get(count..)) { - (Some(first), Some(rest)) => { - self.src = rest; - Ok(first) - } - _ => Err(AduParseError::InsufficientBytes), - } - } -} - -impl<'a> WriteCursor<'a> { - #[cfg_attr(feature = "no-panic", no_panic)] - #[cfg(feature = "serial")] - pub(crate) fn get(&self, range: Range) -> Option<&[u8]> { - self.dest.get(range) - } - - #[cfg_attr(feature = "no-panic", no_panic)] - pub(crate) fn new(dest: &'a mut [u8]) -> WriteCursor<'a> { - WriteCursor { dest, pos: 0 } - } - - #[cfg_attr(feature = "no-panic", no_panic)] - pub(crate) fn position(&self) -> usize { - self.pos - } - - #[cfg_attr(feature = "no-panic", no_panic)] - pub(crate) fn remaining(&self) -> usize { - self.dest.len() - self.pos - } - - #[cfg_attr(feature = "no-panic", no_panic)] - pub(crate) fn seek_from_current(&mut self, count: usize) -> Result<(), InternalError> { - if self.remaining() < count { - return Err(InternalError::BadSeekOperation); - } - self.pos += count; - Ok(()) - } - - #[cfg_attr(feature = "no-panic", no_panic)] - pub(crate) fn seek_from_start(&mut self, count: usize) -> Result<(), InternalError> { - if self.dest.len() < count { - return Err(InternalError::BadSeekOperation); - } - self.pos = count; - Ok(()) - } - - #[cfg_attr(feature = "no-panic", no_panic)] - pub(crate) fn write_u8(&mut self, value: u8) -> Result<(), InternalError> { - match self.dest.get_mut(self.pos) { - Some(x) => { - *x = value; - self.pos += 1; - Ok(()) - } - None => Err(InternalError::InsufficientWriteSpace(1, 0)), - } - } - - #[cfg_attr(feature = "no-panic", no_panic)] - pub(crate) fn write_u16_be(&mut self, value: u16) -> Result<(), InternalError> { - if self.remaining() < 2 { - // don't write any bytes if there's isn't space for the whole thing - return Err(InternalError::InsufficientWriteSpace(2, self.remaining())); - } - let upper = ((value & 0xFF00) >> 8) as u8; - let lower = (value & 0x00FF) as u8; - self.write_u8(upper)?; - self.write_u8(lower) - } - - #[cfg_attr(feature = "no-panic", no_panic)] - #[cfg(feature = "serial")] - pub(crate) fn write_u16_le(&mut self, value: u16) -> Result<(), InternalError> { - if self.remaining() < 2 { - // don't write any bytes if there's isn't space for the whole thing - return Err(InternalError::InsufficientWriteSpace(2, self.remaining())); - } - let upper = ((value & 0xFF00) >> 8) as u8; - let lower = (value & 0x00FF) as u8; - self.write_u8(lower)?; - self.write_u8(upper) - } -} diff --git a/rodbus/src/common/frame.rs b/rodbus/src/common/frame.rs index 08674df6..b4b42f46 100644 --- a/rodbus/src/common/frame.rs +++ b/rodbus/src/common/frame.rs @@ -2,7 +2,6 @@ use crate::common::phys::PhysLayer; use std::ops::Range; use crate::common::buffer::ReadBuffer; -use crate::common::cursor::WriteCursor; use crate::common::function::FunctionCode; use crate::common::traits::{Loggable, LoggableDisplay, Serialize}; use crate::error::RequestError; @@ -10,6 +9,8 @@ use crate::tcp::frame::{MbapDisplay, MbapHeader, MbapParser}; use crate::types::UnitId; use crate::{DecodeLevel, ExceptionCode, FrameDecodeLevel}; +use scursor::WriteCursor; + pub(crate) mod constants { const fn max(lhs: usize, rhs: usize) -> usize { if lhs > rhs { diff --git a/rodbus/src/common/mod.rs b/rodbus/src/common/mod.rs index 3f1e8dce..145bf918 100644 --- a/rodbus/src/common/mod.rs +++ b/rodbus/src/common/mod.rs @@ -3,7 +3,6 @@ pub(crate) mod traits; pub(crate) mod bits; pub(crate) mod buffer; -pub(crate) mod cursor; pub(crate) mod frame; mod parse; pub(crate) mod phys; diff --git a/rodbus/src/common/parse.rs b/rodbus/src/common/parse.rs index 7b0a5018..8b6dce04 100644 --- a/rodbus/src/common/parse.rs +++ b/rodbus/src/common/parse.rs @@ -1,8 +1,9 @@ -use crate::common::cursor::ReadCursor; use crate::common::traits::Parse; use crate::error::*; use crate::types::{coil_from_u16, AddressRange, Indexed}; +use scursor::ReadCursor; + impl Parse for AddressRange { fn parse(cursor: &mut ReadCursor) -> Result { Ok(AddressRange::try_from( @@ -29,11 +30,12 @@ impl Parse for Indexed { #[cfg(test)] mod coils { - use crate::common::cursor::ReadCursor; use crate::common::traits::Parse; use crate::error::AduParseError; use crate::types::Indexed; + use scursor::ReadCursor; + #[test] fn parse_fails_for_unknown_coil_value() { let mut cursor = ReadCursor::new(&[0x00, 0x01, 0xAB, 0xCD]); diff --git a/rodbus/src/common/serialize.rs b/rodbus/src/common/serialize.rs index 0a178265..753f3659 100644 --- a/rodbus/src/common/serialize.rs +++ b/rodbus/src/common/serialize.rs @@ -1,8 +1,6 @@ use std::convert::TryFrom; use crate::client::WriteMultiple; -use crate::common::cursor::ReadCursor; -use crate::common::cursor::WriteCursor; use crate::common::traits::Loggable; use crate::common::traits::Parse; use crate::common::traits::Serialize; @@ -13,6 +11,8 @@ use crate::types::{ RegisterIterator, RegisterIteratorDisplay, }; +use scursor::{ReadCursor, WriteCursor}; + pub(crate) fn calc_bytes_for_bits(num_bits: usize) -> Result { let div_8 = num_bits / 8; diff --git a/rodbus/src/common/traits.rs b/rodbus/src/common/traits.rs index 130ba47a..86a80a7b 100644 --- a/rodbus/src/common/traits.rs +++ b/rodbus/src/common/traits.rs @@ -1,8 +1,9 @@ -use crate::common::cursor::*; use crate::decode::AppDecodeLevel; use crate::error::*; use crate::ExceptionCode; +use scursor::{ReadCursor, WriteCursor}; + pub(crate) trait Serialize { fn serialize(&self, cursor: &mut WriteCursor) -> Result<(), RequestError>; } diff --git a/rodbus/src/error.rs b/rodbus/src/error.rs index 16d4c057..11a994c4 100644 --- a/rodbus/src/error.rs +++ b/rodbus/src/error.rs @@ -1,3 +1,5 @@ +use scursor::WriteError; + /// The task processing requests has terminated #[derive(Clone, Copy, Debug)] pub struct Shutdown; @@ -53,6 +55,19 @@ impl std::fmt::Display for RequestError { } } +impl From for RequestError { + fn from(err: WriteError) -> Self { + match err { + WriteError::WriteOverflow { remaining, written } => { + RequestError::Internal(InternalError::InsufficientWriteSpace(written, remaining)) + } + WriteError::NumericOverflow | WriteError::BadSeek { .. } => { + RequestError::Internal(InternalError::BadSeekOperation) + } + } + } +} + impl From for RequestError { fn from(err: std::io::Error) -> Self { RequestError::Io(err.kind()) @@ -119,6 +134,18 @@ impl From for RequestError { } } +impl From for RequestError { + fn from(_: scursor::ReadError) -> Self { + RequestError::BadResponse(AduParseError::InsufficientBytes) + } +} + +impl From for RequestError { + fn from(x: scursor::TrailingBytes) -> Self { + RequestError::BadResponse(AduParseError::TrailingBytes(x.count.get())) + } +} + /// Errors that can be produced when validating start/count #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum InvalidRange { diff --git a/rodbus/src/serial/frame.rs b/rodbus/src/serial/frame.rs index 846ff8ce..a76b3fc0 100644 --- a/rodbus/src/serial/frame.rs +++ b/rodbus/src/serial/frame.rs @@ -1,5 +1,4 @@ use crate::common::buffer::ReadBuffer; -use crate::common::cursor::WriteCursor; use crate::common::frame::{ Frame, FrameDestination, FrameHeader, FrameInfo, FrameType, FunctionField, }; @@ -9,6 +8,8 @@ use crate::decode::FrameDecodeLevel; use crate::error::{FrameParseError, RequestError}; use crate::types::UnitId; +use scursor::WriteCursor; + pub(crate) mod constants { pub(crate) const HEADER_LENGTH: usize = 1; pub(crate) const FUNCTION_CODE_LENGTH: usize = 1; diff --git a/rodbus/src/server/request.rs b/rodbus/src/server/request.rs index dca0e532..78f2a149 100644 --- a/rodbus/src/server/request.rs +++ b/rodbus/src/server/request.rs @@ -1,4 +1,3 @@ -use crate::common::cursor::ReadCursor; use crate::common::frame::{FrameHeader, FrameWriter, FunctionField}; use crate::common::function::FunctionCode; use crate::common::traits::{Loggable, Parse, Serialize}; @@ -10,6 +9,8 @@ use crate::server::response::{BitWriter, RegisterWriter}; use crate::server::*; use crate::types::*; +use scursor::ReadCursor; + #[derive(Debug)] pub(crate) enum Request<'a> { ReadCoils(ReadBitsRange), @@ -262,7 +263,7 @@ impl std::fmt::Display for RequestDisplay<'_, '_> { #[cfg(test)] mod tests { mod coils { - use crate::common::cursor::ReadCursor; + use scursor::ReadCursor; use super::super::*; use crate::error::AduParseError; @@ -326,7 +327,7 @@ mod tests { } mod registers { - use crate::common::cursor::ReadCursor; + use scursor::ReadCursor; use super::super::*; use crate::error::AduParseError; diff --git a/rodbus/src/server/task.rs b/rodbus/src/server/task.rs index 0fc4aa8f..fbb7bfca 100644 --- a/rodbus/src/server/task.rs +++ b/rodbus/src/server/task.rs @@ -2,7 +2,6 @@ use crate::common::phys::PhysLayer; use crate::server::{Authorization, AuthorizationHandler}; use crate::{DecodeLevel, UnitId}; -use crate::common::cursor::ReadCursor; use crate::common::frame::{ Frame, FrameDestination, FrameHeader, FrameWriter, FramedReader, FunctionField, }; @@ -11,6 +10,8 @@ use crate::error::*; use crate::exception::ExceptionCode; use crate::server::handler::{RequestHandler, ServerHandlerMap}; use crate::server::request::{Request, RequestDisplay}; + +use scursor::ReadCursor; use std::sync::Arc; /// Messages that can be sent to change server settings dynamically diff --git a/rodbus/src/tcp/frame.rs b/rodbus/src/tcp/frame.rs index 894612f9..9ac2002c 100644 --- a/rodbus/src/tcp/frame.rs +++ b/rodbus/src/tcp/frame.rs @@ -1,11 +1,12 @@ use crate::common::buffer::ReadBuffer; -use crate::common::cursor::WriteCursor; use crate::common::frame::{Frame, FrameHeader, FrameInfo, FrameType, FunctionField, TxId}; use crate::common::traits::Serialize; use crate::decode::FrameDecodeLevel; use crate::error::{FrameParseError, RequestError}; use crate::types::UnitId; +use scursor::WriteCursor; + pub(crate) mod constants { pub(crate) const HEADER_LENGTH: usize = 7; pub(crate) const MAX_FRAME_LENGTH: usize = @@ -138,7 +139,7 @@ pub(crate) fn format_mbap( cursor.write_u16_be(tx_id.to_u16())?; cursor.write_u16_be(0)?; // protocol id let len_pos = cursor.position(); - cursor.seek_from_current(2)?; // write the length later + cursor.skip(2)?; // write the length later cursor.write_u8(unit_id.value)?; // unit id let start_pdu = cursor.position(); @@ -151,9 +152,9 @@ pub(crate) fn format_mbap( let mbap_len_field = (end_pdu - start_pdu + 1) as u16; // seek back and write the length, restore to the end of the pdu - cursor.seek_from_start(len_pos)?; + cursor.seek_to(len_pos)?; cursor.write_u16_be(mbap_len_field)?; - cursor.seek_from_start(end_pdu)?; + cursor.seek_to(end_pdu)?; let header = MbapHeader { tx_id, diff --git a/rodbus/src/types.rs b/rodbus/src/types.rs index 5feb80cc..e6fcbf8f 100644 --- a/rodbus/src/types.rs +++ b/rodbus/src/types.rs @@ -1,10 +1,9 @@ use crate::decode::AppDecodeLevel; use crate::error::{AduParseError, InvalidRange}; -use crate::common::cursor::ReadCursor; +use scursor::ReadCursor; + use crate::error::RequestError; -#[cfg(feature = "no-panic")] -use no_panic::no_panic; /// Modbus unit identifier, just a type-safe wrapper around `u8` #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)] @@ -165,7 +164,6 @@ impl std::fmt::Display for RegisterIteratorDisplay<'_> { impl<'a> Iterator for BitIterator<'a> { type Item = Indexed; - #[cfg_attr(feature = "no-panic", no_panic)] fn next(&mut self) -> Option { if self.pos == self.range.count { return None; @@ -184,8 +182,7 @@ impl<'a> Iterator for BitIterator<'a> { } } - // implementing this allows collect to optimize the vector capacity - #[cfg_attr(feature = "no-panic", no_panic)] + /// implementing this allows collect to optimize the vector capacity fn size_hint(&self) -> (usize, Option) { let remaining = (self.range.count - self.pos) as usize; (remaining, Some(remaining)) @@ -195,7 +192,6 @@ impl<'a> Iterator for BitIterator<'a> { impl<'a> Iterator for RegisterIterator<'a> { type Item = Indexed; - #[cfg_attr(feature = "no-panic", no_panic)] fn next(&mut self) -> Option { if self.pos == self.range.count { return None; @@ -214,7 +210,6 @@ impl<'a> Iterator for RegisterIterator<'a> { } // implementing this allows collect to optimize the vector capacity - #[cfg_attr(feature = "no-panic", no_panic)] fn size_hint(&self) -> (usize, Option) { let remaining = (self.range.count - self.pos) as usize; (remaining, Some(remaining)) @@ -394,8 +389,8 @@ mod tests { #[test] fn start_max_count_of_two_overflows() { assert_eq!( - AddressRange::try_from(std::u16::MAX, 2), - Err(InvalidRange::AddressOverflow(std::u16::MAX, 2)) + AddressRange::try_from(u16::MAX, 2), + Err(InvalidRange::AddressOverflow(u16::MAX, 2)) ); }