Struct Port

Source
pub struct Port(/* private fields */);
Expand description

Represents a validated port index, guaranteed to be within the valid range 0..NUMBER_OF_PORTS.

Use Port::try_from to create an instance from a u8. This struct also defines constants for the data values used when controlling a specific port via Modbus “Write Single Register” (function code 0x06). The register address corresponds to the 1-based port index (see Port::address_for_write_register).

Implementations§

Source§

impl Port

Source

pub const MIN: u8 = 0u8

The minimum valid port index (inclusive).

Source

pub const MAX: u8 = 7u8

The maximum valid port index (inclusive).

Source

pub const REG_DATA_SET_PORT_OPEN: Word = 256u16

Register data value to open the specified port (turn relay ON / activate output).

Source

pub const REG_DATA_SET_PORT_CLOSE: Word = 512u16

Register data value to close the specified port (turn relay OFF / deactivate output).

Source

pub const REG_DATA_SET_PORT_TOGGLE: Word = 768u16

Register data value to toggle the state of the specified port (Open <-> Close). Also called “Self-locking”.

Source

pub const REG_DATA_SET_PORT_LATCH: Word = 1_024u16

Register data value to latch the specified port (set this port Open, set all others Close). Also called “Inter-locking”.

Source

pub const REG_DATA_SET_PORT_MOMENTARY: Word = 1_280u16

Register data value to activate the specified port momentarily (Open for ~1 second, then automatically Close). Also called “Non-locking”.

Source

pub const REG_DATA_SET_PORT_DELAY: Word = 1_536u16

Base register data value to initiate a delayed action on the specified port. The actual delay (0-255 seconds) must be added to this value using Port::encode_delay_for_write_register. The action is typically Open -> wait delay -> Close.

Source

pub fn address_for_write_register(&self) -> u16

Returns the Modbus register address for controlling this specific port.

The address is used with Modbus function 0x06 (Write Single Register), where the data written to this address determines the action (e.g., Port::REG_DATA_SET_PORT_OPEN).

§Returns

The u16 Modbus address for controlling this port.

§Example
assert_eq!(Port::try_from(0).unwrap().address_for_write_register(), 0x0001);
assert_eq!(Port::try_from(7).unwrap().address_for_write_register(), 0x0008);
Source

pub fn encode_delay_for_write_register(delay: u8) -> Word

Encodes the register data value (Word) for setting a delayed action on a port.

This combines the command code Port::REG_DATA_SET_PORT_DELAY (in the high byte) with the desired delay duration (in the low byte). The resulting Word should be written to the port’s specific address (see Port::address_for_write_register) using Modbus function 0x06.

§Arguments
  • delay: The delay duration in seconds.
§Returns

The corresponding Word to be written to the register for the delayed action command.

§Example
// Command data to trigger a delayed action after 10 seconds:
let delay_command_data = Port::encode_delay_for_write_register(10);
assert_eq!(delay_command_data, 0x060A); // 0x0600 + 10

// This value (0x060A) would then be written to the target port's Modbus address.
// e.g., for port 3 (address 0x0004): WriteRegister(address=4, value=0x060A)

Methods from Deref<Target = u8>§

1.43.0 · Source

pub const MIN: u8 = 0u8

1.43.0 · Source

pub const MAX: u8 = 255u8

1.53.0 · Source

pub const BITS: u32 = 8u32

1.23.0 · Source

pub fn is_ascii(&self) -> bool

Checks if the value is within the ASCII range.

§Examples
let ascii = 97u8;
let non_ascii = 150u8;

assert!(ascii.is_ascii());
assert!(!non_ascii.is_ascii());
Source

pub fn as_ascii(&self) -> Option<AsciiChar>

🔬This is a nightly-only experimental API. (ascii_char)

If the value of this byte is within the ASCII range, returns it as an ASCII character. Otherwise, returns None.

Source

pub unsafe fn as_ascii_unchecked(&self) -> AsciiChar

🔬This is a nightly-only experimental API. (ascii_char)

Converts this byte to an ASCII character, without checking whether or not it’s valid.

§Safety

This byte must be valid ASCII, or else this is UB.

1.23.0 · Source

pub fn to_ascii_uppercase(&self) -> u8

Makes a copy of the value in its ASCII upper case equivalent.

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, but non-ASCII letters are unchanged.

To uppercase the value in-place, use make_ascii_uppercase.

§Examples
let lowercase_a = 97u8;

assert_eq!(65, lowercase_a.to_ascii_uppercase());
1.23.0 · Source

pub fn to_ascii_lowercase(&self) -> u8

Makes a copy of the value in its ASCII lower case equivalent.

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, but non-ASCII letters are unchanged.

To lowercase the value in-place, use make_ascii_lowercase.

§Examples
let uppercase_a = 65u8;

assert_eq!(97, uppercase_a.to_ascii_lowercase());
1.23.0 · Source

pub fn eq_ignore_ascii_case(&self, other: &u8) -> bool

Checks that two values are an ASCII case-insensitive match.

This is equivalent to to_ascii_lowercase(a) == to_ascii_lowercase(b).

§Examples
let lowercase_a = 97u8;
let uppercase_a = 65u8;

assert!(lowercase_a.eq_ignore_ascii_case(&uppercase_a));
1.24.0 · Source

pub fn is_ascii_alphabetic(&self) -> bool

Checks if the value is an ASCII alphabetic character:

  • U+0041 ‘A’ ..= U+005A ‘Z’, or
  • U+0061 ‘a’ ..= U+007A ‘z’.
§Examples
let uppercase_a = b'A';
let uppercase_g = b'G';
let a = b'a';
let g = b'g';
let zero = b'0';
let percent = b'%';
let space = b' ';
let lf = b'\n';
let esc = b'\x1b';

assert!(uppercase_a.is_ascii_alphabetic());
assert!(uppercase_g.is_ascii_alphabetic());
assert!(a.is_ascii_alphabetic());
assert!(g.is_ascii_alphabetic());
assert!(!zero.is_ascii_alphabetic());
assert!(!percent.is_ascii_alphabetic());
assert!(!space.is_ascii_alphabetic());
assert!(!lf.is_ascii_alphabetic());
assert!(!esc.is_ascii_alphabetic());
1.24.0 · Source

pub fn is_ascii_uppercase(&self) -> bool

Checks if the value is an ASCII uppercase character: U+0041 ‘A’ ..= U+005A ‘Z’.

§Examples
let uppercase_a = b'A';
let uppercase_g = b'G';
let a = b'a';
let g = b'g';
let zero = b'0';
let percent = b'%';
let space = b' ';
let lf = b'\n';
let esc = b'\x1b';

assert!(uppercase_a.is_ascii_uppercase());
assert!(uppercase_g.is_ascii_uppercase());
assert!(!a.is_ascii_uppercase());
assert!(!g.is_ascii_uppercase());
assert!(!zero.is_ascii_uppercase());
assert!(!percent.is_ascii_uppercase());
assert!(!space.is_ascii_uppercase());
assert!(!lf.is_ascii_uppercase());
assert!(!esc.is_ascii_uppercase());
1.24.0 · Source

pub fn is_ascii_lowercase(&self) -> bool

Checks if the value is an ASCII lowercase character: U+0061 ‘a’ ..= U+007A ‘z’.

§Examples
let uppercase_a = b'A';
let uppercase_g = b'G';
let a = b'a';
let g = b'g';
let zero = b'0';
let percent = b'%';
let space = b' ';
let lf = b'\n';
let esc = b'\x1b';

assert!(!uppercase_a.is_ascii_lowercase());
assert!(!uppercase_g.is_ascii_lowercase());
assert!(a.is_ascii_lowercase());
assert!(g.is_ascii_lowercase());
assert!(!zero.is_ascii_lowercase());
assert!(!percent.is_ascii_lowercase());
assert!(!space.is_ascii_lowercase());
assert!(!lf.is_ascii_lowercase());
assert!(!esc.is_ascii_lowercase());
1.24.0 · Source

pub fn is_ascii_alphanumeric(&self) -> bool

Checks if the value is an ASCII alphanumeric character:

  • U+0041 ‘A’ ..= U+005A ‘Z’, or
  • U+0061 ‘a’ ..= U+007A ‘z’, or
  • U+0030 ‘0’ ..= U+0039 ‘9’.
§Examples
let uppercase_a = b'A';
let uppercase_g = b'G';
let a = b'a';
let g = b'g';
let zero = b'0';
let percent = b'%';
let space = b' ';
let lf = b'\n';
let esc = b'\x1b';

assert!(uppercase_a.is_ascii_alphanumeric());
assert!(uppercase_g.is_ascii_alphanumeric());
assert!(a.is_ascii_alphanumeric());
assert!(g.is_ascii_alphanumeric());
assert!(zero.is_ascii_alphanumeric());
assert!(!percent.is_ascii_alphanumeric());
assert!(!space.is_ascii_alphanumeric());
assert!(!lf.is_ascii_alphanumeric());
assert!(!esc.is_ascii_alphanumeric());
1.24.0 · Source

pub fn is_ascii_digit(&self) -> bool

Checks if the value is an ASCII decimal digit: U+0030 ‘0’ ..= U+0039 ‘9’.

§Examples
let uppercase_a = b'A';
let uppercase_g = b'G';
let a = b'a';
let g = b'g';
let zero = b'0';
let percent = b'%';
let space = b' ';
let lf = b'\n';
let esc = b'\x1b';

assert!(!uppercase_a.is_ascii_digit());
assert!(!uppercase_g.is_ascii_digit());
assert!(!a.is_ascii_digit());
assert!(!g.is_ascii_digit());
assert!(zero.is_ascii_digit());
assert!(!percent.is_ascii_digit());
assert!(!space.is_ascii_digit());
assert!(!lf.is_ascii_digit());
assert!(!esc.is_ascii_digit());
Source

pub fn is_ascii_octdigit(&self) -> bool

🔬This is a nightly-only experimental API. (is_ascii_octdigit)

Checks if the value is an ASCII octal digit: U+0030 ‘0’ ..= U+0037 ‘7’.

§Examples
#![feature(is_ascii_octdigit)]

let uppercase_a = b'A';
let a = b'a';
let zero = b'0';
let seven = b'7';
let nine = b'9';
let percent = b'%';
let lf = b'\n';

assert!(!uppercase_a.is_ascii_octdigit());
assert!(!a.is_ascii_octdigit());
assert!(zero.is_ascii_octdigit());
assert!(seven.is_ascii_octdigit());
assert!(!nine.is_ascii_octdigit());
assert!(!percent.is_ascii_octdigit());
assert!(!lf.is_ascii_octdigit());
1.24.0 · Source

pub fn is_ascii_hexdigit(&self) -> bool

Checks if the value is an ASCII hexadecimal digit:

  • U+0030 ‘0’ ..= U+0039 ‘9’, or
  • U+0041 ‘A’ ..= U+0046 ‘F’, or
  • U+0061 ‘a’ ..= U+0066 ‘f’.
§Examples
let uppercase_a = b'A';
let uppercase_g = b'G';
let a = b'a';
let g = b'g';
let zero = b'0';
let percent = b'%';
let space = b' ';
let lf = b'\n';
let esc = b'\x1b';

assert!(uppercase_a.is_ascii_hexdigit());
assert!(!uppercase_g.is_ascii_hexdigit());
assert!(a.is_ascii_hexdigit());
assert!(!g.is_ascii_hexdigit());
assert!(zero.is_ascii_hexdigit());
assert!(!percent.is_ascii_hexdigit());
assert!(!space.is_ascii_hexdigit());
assert!(!lf.is_ascii_hexdigit());
assert!(!esc.is_ascii_hexdigit());
1.24.0 · Source

pub fn is_ascii_punctuation(&self) -> bool

Checks if the value is an ASCII punctuation character:

  • U+0021 ..= U+002F ! " # $ % & ' ( ) * + , - . /, or
  • U+003A ..= U+0040 : ; < = > ? @, or
  • U+005B ..= U+0060 [ \ ] ^ _ `, or
  • U+007B ..= U+007E { | } ~
§Examples
let uppercase_a = b'A';
let uppercase_g = b'G';
let a = b'a';
let g = b'g';
let zero = b'0';
let percent = b'%';
let space = b' ';
let lf = b'\n';
let esc = b'\x1b';

assert!(!uppercase_a.is_ascii_punctuation());
assert!(!uppercase_g.is_ascii_punctuation());
assert!(!a.is_ascii_punctuation());
assert!(!g.is_ascii_punctuation());
assert!(!zero.is_ascii_punctuation());
assert!(percent.is_ascii_punctuation());
assert!(!space.is_ascii_punctuation());
assert!(!lf.is_ascii_punctuation());
assert!(!esc.is_ascii_punctuation());
1.24.0 · Source

pub fn is_ascii_graphic(&self) -> bool

Checks if the value is an ASCII graphic character: U+0021 ‘!’ ..= U+007E ‘~’.

§Examples
let uppercase_a = b'A';
let uppercase_g = b'G';
let a = b'a';
let g = b'g';
let zero = b'0';
let percent = b'%';
let space = b' ';
let lf = b'\n';
let esc = b'\x1b';

assert!(uppercase_a.is_ascii_graphic());
assert!(uppercase_g.is_ascii_graphic());
assert!(a.is_ascii_graphic());
assert!(g.is_ascii_graphic());
assert!(zero.is_ascii_graphic());
assert!(percent.is_ascii_graphic());
assert!(!space.is_ascii_graphic());
assert!(!lf.is_ascii_graphic());
assert!(!esc.is_ascii_graphic());
1.24.0 · Source

pub fn is_ascii_whitespace(&self) -> bool

Checks if the value is an ASCII whitespace character: U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED, U+000C FORM FEED, or U+000D CARRIAGE RETURN.

Rust uses the WhatWG Infra Standard’s definition of ASCII whitespace. There are several other definitions in wide use. For instance, the POSIX locale includes U+000B VERTICAL TAB as well as all the above characters, but—from the very same specification—the default rule for “field splitting” in the Bourne shell considers only SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.

If you are writing a program that will process an existing file format, check what that format’s definition of whitespace is before using this function.

§Examples
let uppercase_a = b'A';
let uppercase_g = b'G';
let a = b'a';
let g = b'g';
let zero = b'0';
let percent = b'%';
let space = b' ';
let lf = b'\n';
let esc = b'\x1b';

assert!(!uppercase_a.is_ascii_whitespace());
assert!(!uppercase_g.is_ascii_whitespace());
assert!(!a.is_ascii_whitespace());
assert!(!g.is_ascii_whitespace());
assert!(!zero.is_ascii_whitespace());
assert!(!percent.is_ascii_whitespace());
assert!(space.is_ascii_whitespace());
assert!(lf.is_ascii_whitespace());
assert!(!esc.is_ascii_whitespace());
1.24.0 · Source

pub fn is_ascii_control(&self) -> bool

Checks if the value is an ASCII control character: U+0000 NUL ..= U+001F UNIT SEPARATOR, or U+007F DELETE. Note that most ASCII whitespace characters are control characters, but SPACE is not.

§Examples
let uppercase_a = b'A';
let uppercase_g = b'G';
let a = b'a';
let g = b'g';
let zero = b'0';
let percent = b'%';
let space = b' ';
let lf = b'\n';
let esc = b'\x1b';

assert!(!uppercase_a.is_ascii_control());
assert!(!uppercase_g.is_ascii_control());
assert!(!a.is_ascii_control());
assert!(!g.is_ascii_control());
assert!(!zero.is_ascii_control());
assert!(!percent.is_ascii_control());
assert!(!space.is_ascii_control());
assert!(lf.is_ascii_control());
assert!(esc.is_ascii_control());

Trait Implementations§

Source§

impl Clone for Port

Source§

fn clone(&self) -> Port

Returns a duplicate of the value. Read more
1.0.0 · Source§

const fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Port

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Deref for Port

Allows accessing the inner u8 port index value directly.

Source§

type Target = u8

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl Hash for Port

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for Port

Source§

fn eq(&self, other: &Port) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

const fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl TryFrom<u8> for Port

Source§

fn try_from(value: u8) -> Result<Self, Self::Error>

Attempts to create a Port from a u8 value, validating its 0-based range.

§Arguments
  • value: The port index to validate.
§Returns
  • Ok(Port): If the value is within the valid range [Port::MIN, Port::MAX].
  • Err(ErrorPortOutOfRange): If the value is outside the valid range.
§Example
let max_port_index = (NUMBER_OF_PORTS - 1) as u8; // Should be 7
assert!(Port::try_from(0).is_ok());
assert!(Port::try_from(max_port_index).is_ok());
let invalid_index = max_port_index + 1; // Should be 8
assert_eq!(Port::try_from(invalid_index).unwrap_err(), ErrorPortOutOfRange(invalid_index));
Source§

type Error = ErrorPortOutOfRange

The type returned in the event of a conversion error.
Source§

impl Copy for Port

Source§

impl Eq for Port

Source§

impl StructuralPartialEq for Port

Auto Trait Implementations§

§

impl Freeze for Port

§

impl RefUnwindSafe for Port

§

impl Send for Port

§

impl Sync for Port

§

impl Unpin for Port

§

impl UnwindSafe for Port

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.