forked from lavina/lavina
				
			Compare commits
	
		
			2 Commits
		
	
	
		
			887fd95194
			...
			16844f5b85
		
	
	| Author | SHA1 | Date | 
|---|---|---|
| 
							
							
								
									
								
								 | 
						16844f5b85 | |
| 
							
							
								
									
								
								 | 
						1373767d7f | 
| 
						 | 
					@ -7,6 +7,7 @@ use nonempty::nonempty;
 | 
				
			||||||
use nonempty::NonEmpty;
 | 
					use nonempty::NonEmpty;
 | 
				
			||||||
use prometheus::{IntCounter, IntGauge, Registry as MetricsRegistry};
 | 
					use prometheus::{IntCounter, IntGauge, Registry as MetricsRegistry};
 | 
				
			||||||
use serde::Deserialize;
 | 
					use serde::Deserialize;
 | 
				
			||||||
 | 
					use tokio::io::AsyncReadExt;
 | 
				
			||||||
use tokio::io::{AsyncBufReadExt, AsyncWrite, AsyncWriteExt, BufReader, BufWriter};
 | 
					use tokio::io::{AsyncBufReadExt, AsyncWrite, AsyncWriteExt, BufReader, BufWriter};
 | 
				
			||||||
use tokio::net::tcp::{ReadHalf, WriteHalf};
 | 
					use tokio::net::tcp::{ReadHalf, WriteHalf};
 | 
				
			||||||
use tokio::net::{TcpListener, TcpStream};
 | 
					use tokio::net::{TcpListener, TcpStream};
 | 
				
			||||||
| 
						 | 
					@ -96,7 +97,7 @@ async fn handle_registration<'a>(
 | 
				
			||||||
    let mut pass: Option<Str> = None;
 | 
					    let mut pass: Option<Str> = None;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let user = loop {
 | 
					    let user = loop {
 | 
				
			||||||
        let res = reader.read_until(b'\n', &mut buffer).await;
 | 
					        let res = read_irc_message(reader, &mut buffer).await;
 | 
				
			||||||
        let res = match res {
 | 
					        let res = match res {
 | 
				
			||||||
            Ok(len) => {
 | 
					            Ok(len) => {
 | 
				
			||||||
                if len == 0 {
 | 
					                if len == 0 {
 | 
				
			||||||
| 
						 | 
					@ -252,7 +253,7 @@ async fn handle_registered_socket<'a>(
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
        select! {
 | 
					        select! {
 | 
				
			||||||
            biased;
 | 
					            biased;
 | 
				
			||||||
            len = reader.read_until(b'\n', &mut buffer) => {
 | 
					            len = read_irc_message(reader, &mut buffer) => {
 | 
				
			||||||
                let len = len?;
 | 
					                let len = len?;
 | 
				
			||||||
                let len = if len == 0 {
 | 
					                let len = if len == 0 {
 | 
				
			||||||
                    log::info!("EOF, Terminating socket");
 | 
					                    log::info!("EOF, Terminating socket");
 | 
				
			||||||
| 
						 | 
					@ -291,6 +292,21 @@ async fn handle_registered_socket<'a>(
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async fn read_irc_message(reader: &mut BufReader<ReadHalf<'_>>, buf: &mut Vec<u8>) -> Result<usize> {
 | 
				
			||||||
 | 
					    let mut size = 0;
 | 
				
			||||||
 | 
					    'outer: loop {
 | 
				
			||||||
 | 
					        let res = reader.read_until(b'\r', buf).await?;
 | 
				
			||||||
 | 
					        size += res;
 | 
				
			||||||
 | 
					        let next = reader.read_u8().await?;
 | 
				
			||||||
 | 
					        buf.push(next);
 | 
				
			||||||
 | 
					        size += 1;
 | 
				
			||||||
 | 
					        if next != b'\n' { 
 | 
				
			||||||
 | 
					            continue 'outer; 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return Ok(size);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async fn handle_update(
 | 
					async fn handle_update(
 | 
				
			||||||
    config: &ServerConfig,
 | 
					    config: &ServerConfig,
 | 
				
			||||||
    user: &RegisteredUser,
 | 
					    user: &RegisteredUser,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
use super::*;
 | 
					use super::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nom::combinator::opt;
 | 
					use nom::combinator::{all_consuming, opt};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Client-to-server command.
 | 
					/// Client-to-server command.
 | 
				
			||||||
#[derive(Clone, Debug, PartialEq, Eq)]
 | 
					#[derive(Clone, Debug, PartialEq, Eq)]
 | 
				
			||||||
| 
						 | 
					@ -60,8 +60,8 @@ pub enum ClientMessage {
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn client_message(input: &str) -> IResult<&str, ClientMessage> {
 | 
					pub fn client_message(input: &str) -> Result<ClientMessage, anyhow::Error> {
 | 
				
			||||||
    alt((
 | 
					    let (_, m) = all_consuming(alt((
 | 
				
			||||||
        client_message_capability,
 | 
					        client_message_capability,
 | 
				
			||||||
        client_message_ping,
 | 
					        client_message_ping,
 | 
				
			||||||
        client_message_pong,
 | 
					        client_message_pong,
 | 
				
			||||||
| 
						 | 
					@ -75,7 +75,8 @@ pub fn client_message(input: &str) -> IResult<&str, ClientMessage> {
 | 
				
			||||||
        client_message_part,
 | 
					        client_message_part,
 | 
				
			||||||
        client_message_privmsg,
 | 
					        client_message_privmsg,
 | 
				
			||||||
        client_message_quit,
 | 
					        client_message_quit,
 | 
				
			||||||
    ))(input)
 | 
					    )))(input)?;
 | 
				
			||||||
 | 
					    Ok(m)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn client_message_capability(input: &str) -> IResult<&str, ClientMessage> {
 | 
					fn client_message_capability(input: &str) -> IResult<&str, ClientMessage> {
 | 
				
			||||||
| 
						 | 
					@ -89,24 +90,14 @@ fn client_message_ping(input: &str) -> IResult<&str, ClientMessage> {
 | 
				
			||||||
    let (input, _) = tag("PING ")(input)?;
 | 
					    let (input, _) = tag("PING ")(input)?;
 | 
				
			||||||
    let (input, token) = token(input)?;
 | 
					    let (input, token) = token(input)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok((
 | 
					    Ok((input, ClientMessage::Ping { token: token.into() }))
 | 
				
			||||||
        input,
 | 
					 | 
				
			||||||
        ClientMessage::Ping {
 | 
					 | 
				
			||||||
            token: token.into(),
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn client_message_pong(input: &str) -> IResult<&str, ClientMessage> {
 | 
					fn client_message_pong(input: &str) -> IResult<&str, ClientMessage> {
 | 
				
			||||||
    let (input, _) = tag("PONG ")(input)?;
 | 
					    let (input, _) = tag("PONG ")(input)?;
 | 
				
			||||||
    let (input, token) = token(input)?;
 | 
					    let (input, token) = token(input)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok((
 | 
					    Ok((input, ClientMessage::Pong { token: token.into() }))
 | 
				
			||||||
        input,
 | 
					 | 
				
			||||||
        ClientMessage::Pong {
 | 
					 | 
				
			||||||
            token: token.into(),
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn client_message_nick(input: &str) -> IResult<&str, ClientMessage> {
 | 
					fn client_message_nick(input: &str) -> IResult<&str, ClientMessage> {
 | 
				
			||||||
| 
						 | 
					@ -225,12 +216,7 @@ fn client_message_quit(input: &str) -> IResult<&str, ClientMessage> {
 | 
				
			||||||
    let (input, _) = tag("QUIT :")(input)?;
 | 
					    let (input, _) = tag("QUIT :")(input)?;
 | 
				
			||||||
    let (input, reason) = token(input)?;
 | 
					    let (input, reason) = token(input)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok((
 | 
					    Ok((input, ClientMessage::Quit { reason: reason.into() }))
 | 
				
			||||||
        input,
 | 
					 | 
				
			||||||
        ClientMessage::Quit {
 | 
					 | 
				
			||||||
            reason: reason.into(),
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone, Debug, PartialEq, Eq)]
 | 
					#[derive(Clone, Debug, PartialEq, Eq)]
 | 
				
			||||||
| 
						 | 
					@ -292,9 +278,7 @@ mod test {
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
    fn test_client_message_ping() {
 | 
					    fn test_client_message_ping() {
 | 
				
			||||||
        let input = "PING 1337";
 | 
					        let input = "PING 1337";
 | 
				
			||||||
        let expected = ClientMessage::Ping {
 | 
					        let expected = ClientMessage::Ping { token: "1337".into() };
 | 
				
			||||||
            token: "1337".into(),
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let result = client_message(input);
 | 
					        let result = client_message(input);
 | 
				
			||||||
        assert_matches!(result, Ok((_, result)) => assert_eq!(expected, result));
 | 
					        assert_matches!(result, Ok((_, result)) => assert_eq!(expected, result));
 | 
				
			||||||
| 
						 | 
					@ -302,9 +286,7 @@ mod test {
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
    fn test_client_message_pong() {
 | 
					    fn test_client_message_pong() {
 | 
				
			||||||
        let input = "PONG 1337";
 | 
					        let input = "PONG 1337";
 | 
				
			||||||
        let expected = ClientMessage::Pong {
 | 
					        let expected = ClientMessage::Pong { token: "1337".into() };
 | 
				
			||||||
            token: "1337".into(),
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let result = client_message(input);
 | 
					        let result = client_message(input);
 | 
				
			||||||
        assert_matches!(result, Ok((_, result)) => assert_eq!(expected, result));
 | 
					        assert_matches!(result, Ok((_, result)) => assert_eq!(expected, result));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -104,7 +104,7 @@ mod test {
 | 
				
			||||||
    use assert_matches::*;
 | 
					    use assert_matches::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    use super::*;
 | 
					    use super::*;
 | 
				
			||||||
    use crate::testkit::*;
 | 
					    use crate::{testkit::*, client::client_message};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
    fn test_chan_global() {
 | 
					    fn test_chan_global() {
 | 
				
			||||||
| 
						 | 
					@ -153,4 +153,10 @@ mod test {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert_eq!(bytes.as_slice(), input.as_bytes());
 | 
					        assert_eq!(bytes.as_slice(), input.as_bytes());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_aa() {
 | 
				
			||||||
 | 
					        dbg!(client_message("PING asd"));
 | 
				
			||||||
 | 
					        panic!()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,10 @@
 | 
				
			||||||
 | 
					#![allow(unused_variables)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use quick_xml::events::Event;
 | 
					use quick_xml::events::Event;
 | 
				
			||||||
use quick_xml::name::ResolveResult;
 | 
					use quick_xml::name::ResolveResult;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use anyhow::{anyhow, Result};
 | 
					 | 
				
			||||||
use crate::xml::*;
 | 
					use crate::xml::*;
 | 
				
			||||||
 | 
					use anyhow::{anyhow, Result};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub const XMLNS: &'static str = "http://jabber.org/protocol/muc";
 | 
					pub const XMLNS: &'static str = "http://jabber.org/protocol/muc";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,8 +22,8 @@ impl FromXml for History {
 | 
				
			||||||
        |(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
 | 
					        |(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
 | 
				
			||||||
            let mut history = History::default();
 | 
					            let mut history = History::default();
 | 
				
			||||||
            let (bytes, end) = match event {
 | 
					            let (bytes, end) = match event {
 | 
				
			||||||
                Event::Start(bytes) => (bytes, false),
 | 
					                Event::Start(bytes) if bytes.name().0 == Self::NAME.as_bytes() => (bytes, false),
 | 
				
			||||||
                Event::Empty(bytes) => (bytes, true),
 | 
					                Event::Empty(bytes) if bytes.name().0 == Self::NAME.as_bytes() => (bytes, true),
 | 
				
			||||||
                _ => return Err(anyhow!("Unexpected XML event: {event:?}")),
 | 
					                _ => return Err(anyhow!("Unexpected XML event: {event:?}")),
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            for attr in bytes.attributes() {
 | 
					            for attr in bytes.attributes() {
 | 
				
			||||||
| 
						 | 
					@ -72,14 +74,16 @@ impl FromXml for Password {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn parse() -> Self::P {
 | 
					    fn parse() -> Self::P {
 | 
				
			||||||
        |(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
 | 
					        |(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
 | 
				
			||||||
            let Event::Start(bytes) = event else {
 | 
					            let bytes = match event {
 | 
				
			||||||
                return Err(anyhow!("Unexpected XML event: {event:?}"));
 | 
					                Event::Start(bytes) if bytes.name().0 == Self::NAME.as_bytes() => bytes,
 | 
				
			||||||
 | 
					                _ => return Err(anyhow!("Unexpected XML event: {event:?}")),
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            let (namespace, event) = yield;
 | 
					            let (namespace, event) = yield;
 | 
				
			||||||
            let Event::Text(bytes) = event else {
 | 
					            let Event::Text(bytes) = event else {
 | 
				
			||||||
                return Err(anyhow!("Unexpected XML event: {event:?}"));
 | 
					                return Err(anyhow!("Unexpected XML event: {event:?}"));
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            let s = std::str::from_utf8(bytes)?.to_string();
 | 
					            let s = std::str::from_utf8(bytes)?.to_string();
 | 
				
			||||||
 | 
					            let (namespace, event) = yield;
 | 
				
			||||||
            let Event::End(bytes) = event else {
 | 
					            let Event::End(bytes) = event else {
 | 
				
			||||||
                return Err(anyhow!("Unexpected XML event: {event:?}"));
 | 
					                return Err(anyhow!("Unexpected XML event: {event:?}"));
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
| 
						 | 
					@ -106,7 +110,7 @@ impl FromXml for X {
 | 
				
			||||||
    fn parse() -> Self::P {
 | 
					    fn parse() -> Self::P {
 | 
				
			||||||
        |(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
 | 
					        |(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
 | 
				
			||||||
            let mut res = X::default();
 | 
					            let mut res = X::default();
 | 
				
			||||||
            let (bytes, end) = match event {
 | 
					            let (_, end) = match event {
 | 
				
			||||||
                Event::Start(bytes) => (bytes, false),
 | 
					                Event::Start(bytes) => (bytes, false),
 | 
				
			||||||
                Event::Empty(bytes) => (bytes, true),
 | 
					                Event::Empty(bytes) => (bytes, true),
 | 
				
			||||||
                _ => return Err(anyhow!("Unexpected XML event: {event:?}")),
 | 
					                _ => return Err(anyhow!("Unexpected XML event: {event:?}")),
 | 
				
			||||||
| 
						 | 
					@ -138,3 +142,90 @@ impl FromXml for X {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(test)]
 | 
				
			||||||
 | 
					mod test {
 | 
				
			||||||
 | 
					    use super::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_history_success_empty() {
 | 
				
			||||||
 | 
					        let input = "<history/>";
 | 
				
			||||||
 | 
					        let res: History = parse(input).unwrap();
 | 
				
			||||||
 | 
					        let expected = History {
 | 
				
			||||||
 | 
					            maxchars: None,
 | 
				
			||||||
 | 
					            maxstanzas: None,
 | 
				
			||||||
 | 
					            seconds: None,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        assert_eq!(res, expected);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_history_success_empty_attrs() {
 | 
				
			||||||
 | 
					        let input = r#"<history maxchars="1" maxstanzas="2" seconds="4"/>"#;
 | 
				
			||||||
 | 
					        let res: History = parse(input).unwrap();
 | 
				
			||||||
 | 
					        let expected = History {
 | 
				
			||||||
 | 
					            maxchars: Some(1),
 | 
				
			||||||
 | 
					            maxstanzas: Some(2),
 | 
				
			||||||
 | 
					            seconds: Some(4),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        assert_eq!(res, expected);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_history_success_start_end() {
 | 
				
			||||||
 | 
					        let input = r#"<history></history>"#;
 | 
				
			||||||
 | 
					        let res: History = parse(input).unwrap();
 | 
				
			||||||
 | 
					        let expected = History {
 | 
				
			||||||
 | 
					            maxchars: None,
 | 
				
			||||||
 | 
					            maxstanzas: None,
 | 
				
			||||||
 | 
					            seconds: None,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        assert_eq!(res, expected);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_history_incorrect_empty() {
 | 
				
			||||||
 | 
					        let input = r#"<iq/>"#;
 | 
				
			||||||
 | 
					        parse::<History>(input).err().unwrap();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_password_success() {
 | 
				
			||||||
 | 
					        let input = "<password>olala</password>";
 | 
				
			||||||
 | 
					        let res: Password = parse(input).unwrap();
 | 
				
			||||||
 | 
					        let expected = Password("olala".into());
 | 
				
			||||||
 | 
					        assert_eq!(res, expected);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_password_incorrect() {
 | 
				
			||||||
 | 
					        let input = r#"<iq>asdsd</iq>"#;
 | 
				
			||||||
 | 
					        parse::<Password>(input).err().unwrap();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_x_success_empty() {
 | 
				
			||||||
 | 
					        let input = "<x/>";
 | 
				
			||||||
 | 
					        let res: X = parse(input).unwrap();
 | 
				
			||||||
 | 
					        let expected = X {
 | 
				
			||||||
 | 
					            history: None,
 | 
				
			||||||
 | 
					            password: None,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        assert_eq!(res, expected);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_x_success_full() {
 | 
				
			||||||
 | 
					        let input = r#"<x><password>ololo</password><history maxchars="1"/></x>"#;
 | 
				
			||||||
 | 
					        let res: X = parse(input).unwrap();
 | 
				
			||||||
 | 
					        let expected = X {
 | 
				
			||||||
 | 
					            history: Some(History {
 | 
				
			||||||
 | 
					                maxchars: Some(1),
 | 
				
			||||||
 | 
					                maxstanzas: None,
 | 
				
			||||||
 | 
					                seconds: None,
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
 | 
					            password: Some(Password("ololo".into())),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        assert_eq!(res, expected);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ impl Parser for IgnoreParser {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn consume<'a>(
 | 
					    fn consume<'a>(
 | 
				
			||||||
        self: Self,
 | 
					        self: Self,
 | 
				
			||||||
        namespace: ResolveResult,
 | 
					        _: ResolveResult,
 | 
				
			||||||
        event: &Event<'a>,
 | 
					        event: &Event<'a>,
 | 
				
			||||||
    ) -> Continuation<Self, Self::Output> {
 | 
					    ) -> Continuation<Self, Self::Output> {
 | 
				
			||||||
        match self.0 {
 | 
					        match self.0 {
 | 
				
			||||||
| 
						 | 
					@ -58,5 +58,5 @@ impl FromXml for Ignore {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl ToXml for () {
 | 
					impl ToXml for () {
 | 
				
			||||||
    fn serialize(&self, events: &mut Vec<Event<'static>>) {}
 | 
					    fn serialize(&self, _: &mut Vec<Event<'static>>) {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue