Add support for custom_host and custom_port with helper methods
Some checks are pending
ci/woodpecker/push/woodpecker Pipeline is pending

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2023-01-12 19:46:03 +01:00
parent b985906d6d
commit d1d3c57af9
Signed by: pep
GPG key ID: DEDA74AEECA9D0F2

View file

@ -13,7 +13,7 @@ use nom::{
self, self,
branch::alt, branch::alt,
bytes::complete::{tag, take_until, take_until1, take_while, take_while1}, bytes::complete::{tag, take_until, take_until1, take_while, take_while1},
character::complete::{multispace0, space0}, character::complete::{digit1, multispace0, space0},
combinator::{opt, recognize}, combinator::{opt, recognize},
error::{ErrorKind, ParseError}, error::{ErrorKind, ParseError},
multi::{many0, many1}, multi::{many0, many1},
@ -49,6 +49,35 @@ pub struct Account {
pub jid: BareJid, pub jid: BareJid,
pub password: String, pub password: String,
pub resource: Option<String>, pub resource: Option<String>,
pub custom_host: Option<String>,
pub custom_port: Option<u16>,
}
impl Account {
pub fn new<S: Into<String>>(jid: BareJid, password: S) -> Account {
Account {
jid,
password: password.into(),
resource: None,
custom_host: None,
custom_port: None,
}
}
pub fn with_resource<S: Into<String>>(mut self, resource: S) -> Account {
self.resource = Some(resource.into());
self
}
pub fn with_custom_host<S: Into<String>>(mut self, custom_host: S) -> Account {
self.custom_host = Some(custom_host.into());
self
}
pub fn with_custom_port(mut self, custom_port: u16) -> Account {
self.custom_port = Some(custom_port);
self
}
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@ -128,21 +157,35 @@ fn parse_account(s: Span) -> IResult<Span, (AccountName, Account)> {
let name = name.trim(); let name = name.trim();
let mut jid: Option<BareJid> = None; let mut jid: Option<BareJid> = None;
let mut password: Option<String> = None; let mut password: Option<&str> = None;
let mut resource: Option<String> = None; let mut resource: Option<&str> = None;
let mut custom_host: Option<&str> = None;
let mut custom_port: Option<u16> = None;
for line in lines { for line in lines {
let (_, _, attr) = line; let (_, _, attr) = line;
if let Some((key, val)) = attr.split_once(':') { if let Some((key, val)) = attr.split_once(':') {
let key = key.trim();
let val = val.trim(); let val = val.trim();
if key == "jid" { match key.trim() {
jid = Some(BareJid::from_str(val).unwrap()); "jid" => jid = Some(BareJid::from_str(val).unwrap()),
} else if key == "password" { "password" => password = Some(val),
password = Some(String::from(val)); "resource" => resource = Some(val),
} else if key == "resource" { "custom_host" => custom_host = Some(val),
resource = Some(String::from(val)); "custom_port" => {
let val: Span = val.into();
let (j, digits): (Span, Span) = digit1(val)?;
let val = digits.parse::<u16>().or(Err(nom::Err::Error(
nom::error::Error::from_error_kind(j, ErrorKind::Digit),
)))?;
custom_port = Some(val);
}
_ => (),
} }
} else {
return Err(nom::Err::Error(nom::error::Error::from_error_kind(
s,
ErrorKind::Tag,
)));
} }
} }
@ -156,11 +199,11 @@ fn parse_account(s: Span) -> IResult<Span, (AccountName, Account)> {
// Skip comments and empty newlines // Skip comments and empty newlines
let (s, _) = allspaces(s)?; let (s, _) = allspaces(s)?;
let account = Account { let mut account = Account::new(jid.unwrap(), password.unwrap());
jid: jid.unwrap(), account.resource = resource.map(String::from);
password: password.unwrap(), account.custom_host = custom_host.map(String::from);
resource, account.custom_port = custom_port;
};
Ok((s, (String::from(name), account))) Ok((s, (String::from(name), account)))
} }
@ -243,11 +286,10 @@ mod tests {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
fn get_account(name: &str) -> Account { fn get_account(name: &str) -> Account {
Account { Account::new(
jid: BareJid::from_str(format!("{}@localhost", name).as_str()).unwrap(), BareJid::from_str(format!("{}@localhost", name).as_str()).unwrap(),
password: String::from("password"), "password",
resource: None, )
}
} }
#[test] #[test]
@ -298,11 +340,7 @@ mod tests {
let buf3 = "[Client] louise\njid: louise@localhost\n\tpassword: password\n"; let buf3 = "[Client] louise\njid: louise@localhost\n\tpassword: password\n";
let name = String::from("louise"); let name = String::from("louise");
let account = Account { let account = Account::new(BareJid::from_str("louise@localhost").unwrap(), "password");
jid: BareJid::from_str("louise@localhost").unwrap(),
password: String::from("password"),
resource: None,
};
assert_eq!( assert_eq!(
parse_account(buf1.into()), parse_account(buf1.into()),
Ok(( Ok((
@ -312,11 +350,8 @@ mod tests {
); );
let name = String::from("louise's phone"); let name = String::from("louise's phone");
let account = Account { let account = Account::new(BareJid::from_str("louise2@localhost").unwrap(), "password")
jid: BareJid::from_str("louise2@localhost").unwrap(), .with_resource("resource1");
password: String::from("password"),
resource: Some(String::from("resource1")),
};
assert_eq!( assert_eq!(
parse_account(buf2.into()), parse_account(buf2.into()),
Ok(( Ok((
@ -348,19 +383,12 @@ mod tests {
let mut accounts: HashMap<AccountName, Account> = HashMap::new(); let mut accounts: HashMap<AccountName, Account> = HashMap::new();
accounts.insert( accounts.insert(
String::from("louise"), String::from("louise"),
Account { Account::new(BareJid::from_str("louise@localhost").unwrap(), "password"),
jid: BareJid::from_str("louise@localhost").unwrap(),
password: String::from("password"),
resource: None,
},
); );
accounts.insert( accounts.insert(
String::from("須賀子"), String::from("須賀子"),
Account { Account::new(BareJid::from_str("sugako@localhost").unwrap(), "password")
jid: BareJid::from_str("sugako@localhost").unwrap(), .with_resource("resource1"),
password: String::from("password"),
resource: Some(String::from("resource1")),
},
); );
assert_eq!( assert_eq!(
parse_accounts(buf1.into()), parse_accounts(buf1.into()),