mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
refactor: clean up SocketAddr value parser (#777)
- Rename the function - Add more docs explaining the supported formats - Remove support for empty string (just use an `Option`), and remove support for `:` (should be considered a typo) - Reduce allocations of strings
This commit is contained in:
@ -8,7 +8,7 @@ use crate::{
|
|||||||
util::{
|
util::{
|
||||||
chainspec::{chain_spec_value_parser, ChainSpecification},
|
chainspec::{chain_spec_value_parser, ChainSpecification},
|
||||||
init::{init_db, init_genesis},
|
init::{init_db, init_genesis},
|
||||||
socketaddr_value_parser,
|
parse_socket_address,
|
||||||
},
|
},
|
||||||
NetworkOpts,
|
NetworkOpts,
|
||||||
};
|
};
|
||||||
@ -66,7 +66,7 @@ pub struct Command {
|
|||||||
/// Enable Prometheus metrics.
|
/// Enable Prometheus metrics.
|
||||||
///
|
///
|
||||||
/// The metrics will be served at the given interface and port.
|
/// The metrics will be served at the given interface and port.
|
||||||
#[arg(long, value_name = "SOCKET", value_parser = socketaddr_value_parser)]
|
#[arg(long, value_name = "SOCKET", value_parser = parse_socket_address)]
|
||||||
metrics: Option<SocketAddr>,
|
metrics: Option<SocketAddr>,
|
||||||
|
|
||||||
/// Set the chain tip manually for testing purposes.
|
/// Set the chain tip manually for testing purposes.
|
||||||
|
|||||||
@ -38,27 +38,30 @@ pub(crate) fn hash_or_num_value_parser(value: &str) -> Result<BlockHashOrNumber,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse [SocketAddr]
|
/// Parse a [SocketAddr] from a `str`.
|
||||||
pub(crate) fn socketaddr_value_parser(value: &str) -> Result<SocketAddr, eyre::Error> {
|
///
|
||||||
const DEFAULT_DOMAIN: &str = "localhost";
|
/// The following formats are checked:
|
||||||
const DEFAULT_PORT: u16 = 9000;
|
///
|
||||||
let value = if value.is_empty() || value == ":" {
|
/// - If the value can be parsed as a `u16` or starts with `:` it is considered a port, and the
|
||||||
format!("{DEFAULT_DOMAIN}:{DEFAULT_PORT}")
|
/// hostname is set to `localhost`.
|
||||||
} else if value.starts_with(':') {
|
/// - If the value contains `:` it is assumed to be the format `<host>:<port>`
|
||||||
format!("{DEFAULT_DOMAIN}{value}")
|
/// - Otherwise it is assumed to be a hostname
|
||||||
} else if value.ends_with(':') {
|
///
|
||||||
format!("{value}{DEFAULT_PORT}")
|
/// An error is returned if the value is empty.
|
||||||
} else if value.parse::<u16>().is_ok() {
|
pub(crate) fn parse_socket_address(value: &str) -> Result<SocketAddr, eyre::Error> {
|
||||||
format!("{DEFAULT_DOMAIN}:{value}")
|
if value.is_empty() {
|
||||||
} else if value.contains(':') {
|
eyre::bail!("Cannot parse socket address from an empty string");
|
||||||
value.to_string()
|
|
||||||
} else {
|
|
||||||
format!("{value}:{DEFAULT_PORT}")
|
|
||||||
};
|
|
||||||
match value.to_socket_addrs() {
|
|
||||||
Ok(mut iter) => iter.next().ok_or(eyre::Error::msg(format!("\"{value}\""))),
|
|
||||||
Err(e) => Err(eyre::Error::from(e).wrap_err(format!("\"{value}\""))),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if value.starts_with(':') || value.parse::<u16>().is_ok() {
|
||||||
|
("localhost", 9000).to_socket_addrs()
|
||||||
|
} else if value.contains(':') {
|
||||||
|
value.to_socket_addrs()
|
||||||
|
} else {
|
||||||
|
(value, 9000).to_socket_addrs()
|
||||||
|
}?
|
||||||
|
.next()
|
||||||
|
.ok_or_else(|| eyre::eyre!("Could not parse socket address from {}", value))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tracing utility
|
/// Tracing utility
|
||||||
@ -129,16 +132,16 @@ pub mod reth_tracing {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::net::ToSocketAddrs;
|
use super::*;
|
||||||
|
|
||||||
use super::socketaddr_value_parser;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_socketaddr_with_default() {
|
fn parse_socket_addresses() {
|
||||||
let expected = "localhost:9000".to_socket_addrs().unwrap().next().unwrap();
|
for value in ["localhost:9000", ":9000", "9000", "localhost"] {
|
||||||
let test_values = ["localhost:9000", ":9000", "9000", "localhost:", "localhost", ":", ""];
|
let socket_addr = parse_socket_address(value)
|
||||||
for value in test_values {
|
.expect(&format!("could not parse socket address: {}", value));
|
||||||
assert_eq!(socketaddr_value_parser(value).expect("value_parser failed"), expected);
|
|
||||||
|
assert!(socket_addr.ip().is_loopback());
|
||||||
|
assert_eq!(socket_addr.port(), 9000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user