delegate from_uri method to gio::network_address wrapper

This commit is contained in:
yggverse 2024-11-27 15:55:39 +02:00
parent 239786da6a
commit 5737b89278
4 changed files with 35 additions and 22 deletions

View file

@ -11,7 +11,7 @@ pub use response::Response;
use gio::{ use gio::{
prelude::{IOStreamExt, OutputStreamExt, SocketClientExt}, prelude::{IOStreamExt, OutputStreamExt, SocketClientExt},
Cancellable, NetworkAddress, SocketClient, SocketProtocol, TlsCertificate, Cancellable, SocketClient, SocketProtocol, TlsCertificate,
}; };
use glib::{Bytes, Priority, Uri}; use glib::{Bytes, Priority, Uri};
@ -49,7 +49,7 @@ impl Client {
certificate: Option<TlsCertificate>, certificate: Option<TlsCertificate>,
callback: impl Fn(Result<Response, Error>) + 'static, callback: impl Fn(Result<Response, Error>) + 'static,
) { ) {
match network_address_for(&uri) { match crate::gio::network_address::from_uri(&uri, DEFAULT_PORT) {
Ok(network_address) => { Ok(network_address) => {
self.socket.connect_async( self.socket.connect_async(
&network_address.clone(), &network_address.clone(),
@ -78,29 +78,13 @@ impl Client {
}, },
); );
} }
Err(reason) => callback(Err(reason)), Err(reason) => callback(Err(Error::NetworkAddress(reason))),
}; };
} }
} }
// Private helpers // Private helpers
/// [SocketConnectable](https://docs.gtk.org/gio/iface.SocketConnectable.html) /
/// [SNI](https://geminiprotocol.net/docs/protocol-specification.gmi#server-name-indication)
fn network_address_for(uri: &Uri) -> Result<NetworkAddress, Error> {
Ok(NetworkAddress::new(
&match uri.host() {
Some(host) => host,
None => return Err(Error::Connectable(uri.to_string())),
},
if uri.port().is_positive() {
uri.port() as u16
} else {
DEFAULT_PORT
},
))
}
fn request_async( fn request_async(
connection: Connection, connection: Connection,
query: String, query: String,

View file

@ -2,11 +2,12 @@ use std::fmt::{Display, Formatter, Result};
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
Connectable(String),
Connection(super::connection::Error),
Connect(glib::Error), Connect(glib::Error),
Connectable(String),
Connection(crate::client::connection::Error),
NetworkAddress(crate::gio::network_address::Error),
Request(glib::Error), Request(glib::Error),
Response(super::response::Error), Response(crate::client::response::Error),
Write(glib::Error), Write(glib::Error),
} }
@ -22,6 +23,9 @@ impl Display for Error {
Self::Connect(reason) => { Self::Connect(reason) => {
write!(f, "Connect error: {reason}") write!(f, "Connect error: {reason}")
} }
Self::NetworkAddress(reason) => {
write!(f, "Network address error: {reason}")
}
Self::Request(reason) => { Self::Request(reason) => {
write!(f, "Request error: {reason}") write!(f, "Request error: {reason}")
} }

View file

@ -1 +1,2 @@
pub mod memory_input_stream; pub mod memory_input_stream;
pub mod network_address;

View file

@ -0,0 +1,24 @@
pub mod error;
pub use error::Error;
use gio::NetworkAddress;
use glib::Uri;
/// Create new valid [NetworkAddress](https://docs.gtk.org/gio/class.NetworkAddress.html) from [Uri](https://docs.gtk.org/glib/struct.Uri.html)
///
/// Useful as:
/// * shared [SocketConnectable](https://docs.gtk.org/gio/iface.SocketConnectable.html) interface
/// * [SNI](https://geminiprotocol.net/docs/protocol-specification.gmi#server-name-indication) record for TLS connections
pub fn from_uri(uri: &Uri, default_port: u16) -> Result<NetworkAddress, Error> {
Ok(NetworkAddress::new(
&match uri.host() {
Some(host) => host,
None => return Err(Error::Host(uri.to_string())),
},
if uri.port().is_positive() {
uri.port() as u16
} else {
default_port
},
))
}