diff --git a/src/core/player.rs b/src/core/player.rs index 6f63bb8..0c9c4ff 100644 --- a/src/core/player.rs +++ b/src/core/player.rs @@ -27,9 +27,10 @@ use crate::{ /// Opaque player identifier. Cannot contain spaces, must be shorter than 32. #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)] -pub struct PlayerId(Box); +pub struct PlayerId(Str); impl PlayerId { - pub fn from_bytes(bytes: Box) -> Result { + pub fn from(str: impl Into) -> Result { + let bytes = str.into(); if bytes.len() > 32 { return Err(fail("Nickname cannot be longer than 32 symbols")); } @@ -38,10 +39,10 @@ impl PlayerId { } Ok(PlayerId(bytes)) } - pub fn as_bytes(&self) -> &Box { + pub fn as_inner(&self) -> &Str { &self.0 } - pub fn into_bytes(self) -> Box { + pub fn into_inner(self) -> Str { self.0 } } @@ -55,7 +56,7 @@ pub struct PlayerConnection { player_handle: PlayerHandle, } impl PlayerConnection { - pub async fn send_message(&mut self, room_id: RoomId, body: Box) -> Result<()> { + pub async fn send_message(&mut self, room_id: RoomId, body: Str) -> Result<()> { self.player_handle .send_message(room_id, self.connection_id.clone(), body) .await @@ -67,7 +68,7 @@ impl PlayerConnection { .await } - pub async fn change_topic(&mut self, room_id: RoomId, new_topic: ByteVec) -> Result<()> { + pub async fn change_topic(&mut self, room_id: RoomId, new_topic: Str) -> Result<()> { let (promise, deferred) = oneshot(); let cmd = Cmd::ChangeTopic { room_id, @@ -129,7 +130,7 @@ impl PlayerHandle { &self, room_id: RoomId, connection_id: ConnectionId, - body: Box, + body: Str, ) -> Result<()> { let (promise, deferred) = oneshot(); let cmd = Cmd::SendMessage { @@ -186,12 +187,12 @@ pub enum Cmd { }, SendMessage { room_id: RoomId, - body: Box, + body: Str, promise: Promise<()>, }, ChangeTopic { room_id: RoomId, - new_topic: ByteVec, + new_topic: Str, promise: Promise<()>, }, } @@ -206,12 +207,12 @@ pub enum JoinResult { pub enum Updates { RoomTopicChanged { room_id: RoomId, - new_topic: ByteVec, + new_topic: Str, }, NewMessage { room_id: RoomId, author_id: PlayerId, - body: Box, + body: Str, }, RoomJoined { room_id: RoomId, @@ -288,7 +289,7 @@ impl Player { player_id, connections: AnonTable::new(), my_rooms: HashMap::new(), - banned_from: HashSet::from([RoomId::from_bytes("empty".into()).unwrap()]), + banned_from: HashSet::from([RoomId::from("empty").unwrap()]), rx, handle, rooms, diff --git a/src/core/room.rs b/src/core/room.rs index 40269e3..0a4e19c 100644 --- a/src/core/room.rs +++ b/src/core/room.rs @@ -16,9 +16,10 @@ use crate::{ /// Opaque room id #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)] -pub struct RoomId(ByteVec); +pub struct RoomId(Str); impl RoomId { - pub fn from_bytes(bytes: ByteVec) -> Result { + pub fn from(str: impl Into) -> Result { + let bytes = str.into(); if bytes.len() > 32 { return Err(anyhow::Error::msg( "Room name cannot be longer than 32 symbols", @@ -29,10 +30,10 @@ impl RoomId { } Ok(RoomId(bytes)) } - pub fn as_bytes(&self) -> &ByteVec { + pub fn as_inner(&self) -> &Str { &self.0 } - pub fn into_bytes(self) -> ByteVec { + pub fn into_inner(self) -> Str { self.0 } } @@ -112,7 +113,7 @@ impl RoomHandle { lock.broadcast_update(update, player_id).await; } - pub async fn send_message(&self, player_id: PlayerId, body: Box) { + pub async fn send_message(&self, player_id: PlayerId, body: Str) { let lock = self.0.read().await; lock.send_message(player_id, body).await; } @@ -130,7 +131,7 @@ impl RoomHandle { } } - pub async fn set_topic(&mut self, changer_id: PlayerId, new_topic: ByteVec) { + pub async fn set_topic(&mut self, changer_id: PlayerId, new_topic: Str) { let mut lock = self.0.write().await; lock.topic = new_topic.clone(); let update = Updates::RoomTopicChanged { @@ -144,7 +145,7 @@ impl RoomHandle { struct Room { room_id: RoomId, subscriptions: HashMap, - topic: ByteVec, + topic: Str, } impl Room { async fn add_subscriber(&mut self, player_id: PlayerId, player_handle: PlayerHandle) { @@ -157,7 +158,7 @@ impl Room { self.broadcast_update(update, &player_id).await; } - async fn send_message(&self, author_id: PlayerId, body: Box) { + async fn send_message(&self, author_id: PlayerId, body: Str) { tracing::info!("Adding a message to room"); let update = Updates::NewMessage { room_id: self.room_id.clone(), @@ -182,5 +183,5 @@ impl Room { pub struct RoomInfo { pub id: RoomId, pub members: Vec, - pub topic: ByteVec, + pub topic: Str, } diff --git a/src/prelude.rs b/src/prelude.rs index 7e3858e..9488bc2 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -10,8 +10,7 @@ pub mod log { } pub type Result = std::result::Result; - -pub type ByteVec = Box; +pub type Str = std::sync::Arc; pub fn fail(msg: &str) -> anyhow::Error { anyhow::Error::msg(msg.to_owned()) diff --git a/src/projections/irc/mod.rs b/src/projections/irc/mod.rs index ecff751..011398e 100644 --- a/src/projections/irc/mod.rs +++ b/src/projections/irc/mod.rs @@ -23,19 +23,19 @@ mod test; #[derive(Deserialize, Debug, Clone)] pub struct ServerConfig { pub listen_on: SocketAddr, - pub server_name: Box, + pub server_name: Str, } #[derive(Debug)] struct RegisteredUser { - nickname: Box, + nickname: Str, /** * Username is mostly unused in modern IRC. * * [https://stackoverflow.com/questions/31666247/what-is-the-difference-between-the-nick-username-and-real-name-in-irc-and-wha] */ - username: Box, - realname: Box, + username: Str, + realname: Str, } async fn handle_socket( @@ -83,8 +83,8 @@ async fn handle_registration<'a>( ) -> Result { let mut buffer = vec![]; - let mut future_nickname: Option> = None; - let mut future_username: Option<(Box, Box)> = None; + let mut future_nickname: Option = None; + let mut future_username: Option<(Str, Str)> = None; loop { let res = reader.read_until(b'\n', &mut buffer).await; @@ -153,7 +153,7 @@ async fn handle_registered_socket<'a>( let mut buffer = vec![]; log::info!("Handling registered user: {user:?}"); - let player_id = PlayerId::from_bytes(user.nickname.clone())?; + let player_id = PlayerId::from(user.nickname.clone())?; let mut connection = players.connect_to_player(player_id.clone()).await; ServerMessage { @@ -213,7 +213,7 @@ async fn handle_registered_socket<'a>( produce_on_join_cmd_messages( &config, &user, - &Chan::Global(room.id.as_bytes().clone()), + &Chan::Global(room.id.as_inner().clone()), room, writer, ) @@ -280,7 +280,7 @@ async fn handle_update( if player_id == &new_member_id { if let Some(room) = rooms.get_room(&room_id) { let room_info = room.get_room_info().await; - let chan = Chan::Global(room_id.as_bytes().clone()); + let chan = Chan::Global(room_id.as_inner().clone()); produce_on_join_cmd_messages(&config, &user, &chan, &room_info, writer).await?; writer.flush().await?; } else { @@ -289,8 +289,8 @@ async fn handle_update( } else { ServerMessage { tags: vec![], - sender: Some(new_member_id.as_bytes().clone()), - body: ServerMessageBody::Join(Chan::Global(room_id.as_bytes().clone())), + sender: Some(new_member_id.as_inner().clone()), + body: ServerMessageBody::Join(Chan::Global(room_id.as_inner().clone())), } .write_async(writer) .await?; @@ -303,8 +303,8 @@ async fn handle_update( } => { ServerMessage { tags: vec![], - sender: Some(former_member_id.as_bytes().clone()), - body: ServerMessageBody::Part(Chan::Global(room_id.as_bytes().clone())), + sender: Some(former_member_id.as_inner().clone()), + body: ServerMessageBody::Part(Chan::Global(room_id.as_inner().clone())), } .write_async(writer) .await?; @@ -317,9 +317,9 @@ async fn handle_update( } => { ServerMessage { tags: vec![], - sender: Some(author_id.as_bytes().clone()), + sender: Some(author_id.as_inner().clone()), body: ServerMessageBody::PrivateMessage { - target: Recipient::Chan(Chan::Global(room_id.as_bytes().clone())), + target: Recipient::Chan(Chan::Global(room_id.as_inner().clone())), body: body.clone(), }, } @@ -333,7 +333,7 @@ async fn handle_update( sender: Some(config.server_name.clone()), body: ServerMessageBody::N332Topic { client: user.nickname.clone(), - chat: Chan::Global(room_id.as_bytes().clone()), + chat: Chan::Global(room_id.as_inner().clone()), topic: new_topic, }, } @@ -345,8 +345,8 @@ async fn handle_update( // TODO think about the case when the user was banned, but was not in the room - no need to send PART in this case ServerMessage { tags: vec![], - sender: Some(player_id.as_bytes().clone()), - body: ServerMessageBody::Part(Chan::Global(room_id.as_bytes().clone())), + sender: Some(player_id.as_inner().clone()), + body: ServerMessageBody::Part(Chan::Global(room_id.as_inner().clone())), } .write_async(writer) .await?; @@ -393,7 +393,7 @@ async fn handle_incoming_message( } ClientMessage::PrivateMessage { recipient, body } => match recipient { Recipient::Chan(Chan::Global(chan)) => { - let room_id = RoomId::from_bytes(chan)?; + let room_id = RoomId::from(chan)?; user_handle.send_message(room_id, body).await?; }, _ => log::warn!("Unsupported target type"), @@ -401,7 +401,7 @@ async fn handle_incoming_message( ClientMessage::Topic { chan, topic } => { match chan { Chan::Global(chan) => { - let room_id = RoomId::from_bytes(chan)?; + let room_id = RoomId::from(chan)?; user_handle .change_topic(room_id.clone(), topic.clone()) .await?; @@ -410,7 +410,7 @@ async fn handle_incoming_message( sender: Some(config.server_name.clone()), body: ServerMessageBody::N332Topic { client: user.nickname.clone(), - chat: Chan::Global(room_id.as_bytes().clone()), + chat: Chan::Global(room_id.as_inner().clone()), topic, }, } @@ -447,14 +447,14 @@ async fn handle_incoming_message( writer.flush().await?; } Recipient::Chan(Chan::Global(chan)) => { - let room = rooms.get_room(&RoomId::from_bytes(chan.clone())?); + let room = rooms.get_room(&RoomId::from(chan.clone())?); if let Some(room) = room { let room_info = room.get_room_info().await; for member in room_info.members { ServerMessage { tags: vec![], sender: Some(config.server_name.clone()), - body: user_to_who_msg(config, user, member.as_bytes()), + body: user_to_who_msg(config, user, member.as_inner()), } .write_async(writer) .await?; @@ -519,7 +519,7 @@ async fn handle_incoming_message( fn user_to_who_msg( config: &ServerConfig, requestor: &RegisteredUser, - target_user_nickname: &ByteVec, + target_user_nickname: &Str, ) -> ServerMessageBody { // Username is equal to nickname let username = format!("~{target_user_nickname}").into(); @@ -549,7 +549,7 @@ async fn handle_join( ) -> Result<()> { match chan { Chan::Global(chan_name) => { - let room_id = RoomId::from_bytes(chan_name.clone())?; + let room_id = RoomId::from(chan_name.clone())?; if let JoinResult::Success(room_info) = user_handle.join_room(room_id).await? { produce_on_join_cmd_messages(&config, &user, chan, &room_info, writer).await?; } else { @@ -580,7 +580,7 @@ async fn handle_part( writer: &mut (impl AsyncWrite + Unpin), ) -> Result<()> { if let Chan::Global(chan_name) = chan { - let room_id = RoomId::from_bytes(chan_name.clone())?; + let room_id = RoomId::from(chan_name.clone())?; user_handle.leave_room(room_id).await?; ServerMessage { tags: vec![], @@ -622,13 +622,13 @@ async fn produce_on_join_cmd_messages( .write_async(writer) .await?; let mut members: String = if let Some(head) = room_info.members.first() { - head.as_bytes().clone() + head.as_inner().clone() } else { user.nickname.clone() - }.into(); + }.as_ref().into(); for i in &room_info.members[1..] { members.push(' '); - members.push_str(i.as_bytes()); + members.push_str(i.as_inner()); } ServerMessage { tags: vec![], diff --git a/src/projections/xmpp/mod.rs b/src/projections/xmpp/mod.rs index 8bcc43f..5524a8d 100644 --- a/src/projections/xmpp/mod.rs +++ b/src/projections/xmpp/mod.rs @@ -253,11 +253,13 @@ async fn socket_auth( let _ = xmpp::sasl::Auth::parse(xml_reader, reader_buf).await?; xmpp::sasl::Success.write_xml(xml_writer).await?; + + let name: Str = "darova".into(); Ok(Authenticated { - player_id: PlayerId::from_bytes("darova".into())?, - xmpp_name: Name("darova".into()), - xmpp_resource: Resource("darova".to_owned()), - xmpp_muc_name: Resource("darova".to_owned()), + player_id: PlayerId::from("darova")?, + xmpp_name: Name(name.clone()), + xmpp_resource: Resource(name.clone()), + xmpp_muc_name: Resource(name), }) } @@ -337,9 +339,9 @@ async fn socket_final( resource: Some(authenticated.xmpp_resource.clone()), }), from: Some(Jid { - name: Some(Name(room_id.into_bytes().into())), + name: Some(Name(room_id.into_inner().into())), server: Server("rooms.localhost".into()), - resource: Some(Resource(author_id.into_bytes().into())), + resource: Some(Resource(author_id.into_inner().into())), }), id: None, r#type: xmpp::client::MessageType::Groupchat, @@ -391,10 +393,10 @@ async fn handle_packet( resource: _, }) = m.to { - if server.0 == "rooms.localhost" && m.r#type == MessageType::Groupchat { + if server.0.as_ref() == "rooms.localhost" && m.r#type == MessageType::Groupchat { user_handle .send_message( - RoomId::from_bytes(name.0.clone().into())?, + RoomId::from(name.0.clone())?, m.body.clone().into(), ) .await?; @@ -446,7 +448,7 @@ async fn handle_packet( }) = p.to { let a = user_handle - .join_room(RoomId::from_bytes(name.0.clone())?) + .join_room(RoomId::from(name.0.clone())?) .await?; Presence::<()> { to: Some(Jid { @@ -484,8 +486,8 @@ async fn handle_iq(output: &mut Vec>, iq: Iq, rooms r#type: xmpp::client::IqType::Result, body: BindResponse(Jid { name: Some(Name("darova".into())), - server: Server("localhost".to_string()), - resource: Some(Resource("kek".to_string())), + server: Server("localhost".into()), + resource: Some(Resource("kek".into())), }), }; req.serialize(output); @@ -592,7 +594,7 @@ async fn disco_items(to: Option<&str>, req: &ItemQuery, rooms: &RoomRegistry) -> vec![Item { jid: Jid { name: None, - server: Server("rooms.localhost".to_string()), + server: Server("rooms.localhost".into()), resource: None, }, name: None, @@ -605,8 +607,8 @@ async fn disco_items(to: Option<&str>, req: &ItemQuery, rooms: &RoomRegistry) -> .into_iter() .map(|room_info| Item { jid: Jid { - name: Some(Name(room_info.id.into_bytes())), - server: Server("rooms.localhost".to_string()), + name: Some(Name(room_info.id.into_inner())), + server: Server("rooms.localhost".into()), resource: None, }, name: None, diff --git a/src/protos/irc/client.rs b/src/protos/irc/client.rs index 8776394..a0accd0 100644 --- a/src/protos/irc/client.rs +++ b/src/protos/irc/client.rs @@ -9,20 +9,20 @@ pub enum ClientMessage { }, /// PING Ping { - token: Box, + token: Str, }, /// PONG Pong { - token: Box, + token: Str, }, /// NICK Nick { - nickname: Box, + nickname: Str, }, /// USER 0 * : User { - username: Box, - realname: Box, + username: Str, + realname: Str, }, /// JOIN Join(Chan), @@ -37,20 +37,20 @@ pub enum ClientMessage { /// TOPIC : Topic { chan: Chan, - topic: Box, + topic: Str, }, Part { chan: Chan, - message: Box, + message: Str, }, /// PRIVMSG : PrivateMessage { recipient: Recipient, - body: Box, + body: Str, }, /// QUIT : Quit { - reason: Box, + reason: Str, }, } diff --git a/src/protos/irc/mod.rs b/src/protos/irc/mod.rs index 8b4c571..4d65efd 100644 --- a/src/protos/irc/mod.rs +++ b/src/protos/irc/mod.rs @@ -3,6 +3,7 @@ pub mod client; pub mod server; use std::io::Result; +use crate::prelude::Str; use nom::{ branch::alt, @@ -11,12 +12,10 @@ use nom::{ }; use tokio::io::{AsyncWrite, AsyncWriteExt}; -type ByteVec = Box; - /// Single message tag value. #[derive(Clone, Debug, PartialEq, Eq)] pub struct Tag { - key: ByteVec, + key: Str, value: Option, } @@ -31,9 +30,9 @@ fn token(input: &str) -> IResult<&str, &str> { #[derive(Clone, Debug, PartialEq, Eq)] pub enum Chan { /// # — network-global channel, available from any server in the network. - Global(Box), + Global(Str), /// & — server-local channel, available only to connections to the same server. Rarely used in practice. - Local(Box), + Local(Str), } impl Chan { pub async fn write_async(&self, writer: &mut (impl AsyncWrite + Unpin)) -> Result<()> { @@ -69,7 +68,7 @@ fn chan(input: &str) -> IResult<&str, Chan> { #[derive(Clone, Debug, PartialEq, Eq)] pub enum Recipient { - Nick(ByteVec), + Nick(Str), Chan(Chan), } impl Recipient { diff --git a/src/protos/irc/server.rs b/src/protos/irc/server.rs index 4671333..b9deaa6 100644 --- a/src/protos/irc/server.rs +++ b/src/protos/irc/server.rs @@ -9,7 +9,7 @@ pub struct ServerMessage { /// Optional tags section, prefixed with `@` pub tags: Vec, /// Optional server name, prefixed with `:`. - pub sender: Option, + pub sender: Option, pub body: ServerMessageBody, } @@ -44,93 +44,93 @@ pub fn server_message(input: &str) -> IResult<&str, ServerMessage> { #[derive(Clone, Debug, PartialEq, Eq)] pub enum ServerMessageBody { Notice { - first_target: ByteVec, - rest_targets: Vec, - text: ByteVec, + first_target: Str, + rest_targets: Vec, + text: Str, }, Ping { - token: ByteVec, + token: Str, }, Pong { - from: ByteVec, - token: ByteVec, + from: Str, + token: Str, }, PrivateMessage { target: Recipient, - body: ByteVec, + body: Str, }, Join(Chan), Part(Chan), Error { - reason: ByteVec, + reason: Str, }, N001Welcome { - client: ByteVec, - text: ByteVec, + client: Str, + text: Str, }, N002YourHost { - client: ByteVec, - text: ByteVec, + client: Str, + text: Str, }, N003Created { - client: ByteVec, - text: ByteVec, + client: Str, + text: Str, }, N004MyInfo { - client: ByteVec, - hostname: ByteVec, - softname: ByteVec, + client: Str, + hostname: Str, + softname: Str, // TODO user modes, channel modes, channel modes with a parameter }, N005ISupport { - client: ByteVec, - params: ByteVec, // TODO make this a datatype + client: Str, + params: Str, // TODO make this a datatype }, /// Reply to a client's [Mode](crate::protos::irc::client::ClientMessage::Mode) request. N221UserModeIs { - client: ByteVec, - modes: ByteVec, + client: Str, + modes: Str, }, /// Final reply to a client's [Who](crate::protos::irc::client::ClientMessage::Who) request. N315EndOfWho { - client: ByteVec, + client: Str, mask: Recipient, /// Usually `b"End of WHO list"` - msg: ByteVec, + msg: Str, }, N332Topic { - client: ByteVec, + client: Str, chat: Chan, - topic: ByteVec, + topic: Str, }, /// A reply to a client's [Who](crate::protos::irc::client::ClientMessage::Who) request. N352WhoReply { - client: ByteVec, + client: Str, // chan = * - username: ByteVec, + username: Str, /// User's hostname - host: ByteVec, + host: Str, /// Hostname of the server the user is connected to - server: ByteVec, - nickname: ByteVec, + server: Str, + nickname: Str, /// Flags flags: AwayStatus, hops: u8, - realname: ByteVec, + realname: Str, }, N353NamesReply { - client: ByteVec, + client: Str, chan: Chan, - members: ByteVec, // TODO make this a non-empty list with prefixes + members: Str, // TODO make this a non-empty list with prefixes }, N366NamesReplyEnd { - client: ByteVec, + client: Str, chan: Chan, }, N474BannedFromChan { - client: ByteVec, + client: Str, chan: Chan, - message: ByteVec, + message: Str, }, } diff --git a/src/protos/xmpp/bind.rs b/src/protos/xmpp/bind.rs index a2b1d7f..e89e548 100644 --- a/src/protos/xmpp/bind.rs +++ b/src/protos/xmpp/bind.rs @@ -12,13 +12,13 @@ pub const XMLNS: &'static str = "urn:ietf:params:xml:ns:xmpp-bind"; // TODO remove `pub` in newtypes, introduce validation #[derive(PartialEq, Eq, Debug, Clone)] -pub struct Name(pub Box); +pub struct Name(pub Str); #[derive(PartialEq, Eq, Debug, Clone)] -pub struct Server(pub String); +pub struct Server(pub Str); #[derive(PartialEq, Eq, Debug, Clone)] -pub struct Resource(pub String); +pub struct Resource(pub Str); #[derive(PartialEq, Eq, Debug, Clone)] pub struct Jid { @@ -51,10 +51,10 @@ impl Jid { let name = m.get(2).map(|name| Name(name.as_str().into())); let server = m.get(3).unwrap(); - let server = Server(server.as_str().to_string()); + let server = Server(server.as_str().into()); let resource = m .get(5) - .map(|resource| Resource(resource.as_str().to_string())); + .map(|resource| Resource(resource.as_str().into())); Ok(Jid { name, @@ -101,6 +101,7 @@ impl FromXml for BindRequest { } } +// TODO rewrite as a generator impl Parser for BindRequestParser { type Output = Result; @@ -138,7 +139,7 @@ impl Parser for BindRequestParser { let Some(resource) = resource else { return Continuation::Final(Err(ffail!("No resource was provided"))); }; - Continuation::Final(Ok(BindRequest(Resource(resource)))) + Continuation::Final(Ok(BindRequest(Resource(resource.into())))) } _ => Continuation::Final(Err(ffail!("Unexpected XML event: {event:?}"))), }, @@ -208,7 +209,7 @@ mod tests { } } .unwrap(); - assert_eq!(result, BindRequest(Resource("mobile".to_string())),) + assert_eq!(result, BindRequest(Resource("mobile".into())),) } #[test] diff --git a/src/protos/xmpp/client.rs b/src/protos/xmpp/client.rs index 02df4b7..606e03c 100644 --- a/src/protos/xmpp/client.rs +++ b/src/protos/xmpp/client.rs @@ -17,10 +17,10 @@ pub struct Message { pub to: Option, // default is Normal pub r#type: MessageType, - pub lang: Option, + pub lang: Option, - pub subject: Option, - pub body: String, + pub subject: Option, + pub body: Str, } impl FromXmlTag for Message { @@ -53,9 +53,9 @@ struct MessageParserState { id: Option, to: Option, r#type: MessageType, - lang: Option, - subject: Option, - body: Option, + lang: Option, + subject: Option, + body: Option, } impl Parser for MessageParser { type Output = Result; @@ -124,7 +124,7 @@ impl Parser for MessageParser { InSubject(mut state) => match event { Event::Text(ref bytes) => { let subject = fail_fast!(std::str::from_utf8(&*bytes)); - state.subject = Some(subject.to_string()); + state.subject = Some(subject.into()); Continuation::Continue(InSubject(state).into()) } Event::End(_) => Continuation::Continue(Outer(state).into()), @@ -133,7 +133,7 @@ impl Parser for MessageParser { InBody(mut state) => match event { Event::Text(ref bytes) => match std::str::from_utf8(&*bytes) { Ok(subject) => { - state.body = Some(subject.to_string()); + state.body = Some(subject.into()); Continuation::Continue(InBody(state).into()) } Err(err) => Continuation::Final(Err(err.into())), @@ -614,13 +614,13 @@ mod tests { id: Some("aacea".to_string()), to: Some(Jid { name: Some(Name("nikita".into())), - server: Server("vlnv.dev".to_owned()), + server: Server("vlnv.dev".into()), resource: None }), r#type: MessageType::Chat, lang: None, - subject: Some("daa".to_string()), - body: "bbb".to_string(), + subject: Some("daa".into()), + body: "bbb".into(), } ) } @@ -655,7 +655,7 @@ mod tests { id: "bind_1".to_string(), to: None, r#type: IqType::Set, - body: BindRequest(Resource("mobile".to_string())) + body: BindRequest(Resource("mobile".into())) } ) }