~liz/yooper

a1543f7eed3a29fc1c1323c23ead9e3f9fcce30b — Ellie Frost 2 years ago 3f064aa
Move ssdp to submodule
18 files changed, 71 insertions(+), 109 deletions(-)

M yooper/src/lib.rs
M yooper/src/main.rs
D yooper/src/packet/encoder.rs
D yooper/src/rnsplit.rs
R yooper/src/{message.rs => ssdp/message.rs}
R yooper/src/{message/codec.rs => ssdp/message/codec.rs}
R yooper/src/{message/tests.rs => ssdp/message/tests.rs}
R yooper/src/{message/types.rs => ssdp/message/types.rs}
A yooper/src/ssdp/mod.rs
R yooper/src/{packet.rs => ssdp/packet.rs}
R yooper/src/{packet/decoder.rs => ssdp/packet/decoder.rs}
A yooper/src/ssdp/packet/encoder.rs
R yooper/src/{testdata/msearch.bin => ssdp/testdata/msearch.bin}
R yooper/src/{testdata/notify.bin => ssdp/testdata/notify.bin}
R yooper/src/{testdata/response.bin => ssdp/testdata/response.bin}
R yooper/src/{tests.rs => ssdp/tests.rs}
M yooper_derive/src/from_packet.rs
M yooper_derive/src/to_packet.rs
M yooper/src/lib.rs => yooper/src/lib.rs +1 -10
@@ 1,13 1,4 @@
mod errors;
mod message;
mod packet;
pub mod ssdp;

pub use errors::Error;
pub use message::{Message, SSDPMessageCodec};
pub use packet::{
    FromHeaders, FromPacket, Headers, Packet, PacketType, SSDPDecoder, SSDPEncoder, ToHeaders,
    ToPacket,
};

#[cfg(test)]
pub mod tests;

M yooper/src/main.rs => yooper/src/main.rs +1 -1
@@ 34,7 34,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
    //     .send_to(discovery.as_bytes(), (SSDP_ADDRESS, SSDP_PORT))
    //     .await?;

    let mut framed = UdpFramed::new(socket, yooper::SSDPMessageCodec::new());
    let mut framed = UdpFramed::new(socket, yooper::ssdp::message::Codec::new());

    loop {
        let n = framed.next().await;

D yooper/src/packet/encoder.rs => yooper/src/packet/encoder.rs +0 -57
@@ 1,57 0,0 @@
use bytes::BytesMut;
use tokio_util::codec::Encoder;

use super::Packet;
use crate::errors::Error;
use std::fmt::Write;

#[derive(Default)]
pub struct SSDPEncoder {}

impl Encoder<Packet> for SSDPEncoder {
    type Error = Error;

    #[allow(clippy::write_with_newline)]
    fn encode(&mut self, p: Packet, dst: &mut BytesMut) -> Result<(), Self::Error> {
        write!(dst, "{}\r\n", p.typ.to_string())?;
        p.headers
            .iter()
            .map(|(k, v)| write!(dst, "{}: {}\r\n", k, v))
            .collect::<Result<(), std::fmt::Error>>()?;
        write!(dst, "\r\n")?;
        Ok(())
    }
}

// impl Encoder<Message> for SSDPEncoder {
//     type Error = Error;
//     #[allow(clippy::write_with_newline)]
//     fn encode(&mut self, m: Message, dst: &mut BytesMut) -> Result<(), Self::Error> {
//         use Message::*;

//         match m {
//             MSearch {
//                 max_wait,
//                 target,
//                 user_agent,
//                 tcp_port,
//                 friendly_name,
//                 uuid,
//             } => {
//                 write!(dst, "M-SEARCH * HTTP/1.1\r\n")?;
//                 write_header(dst, "host", &format!("{}:{}", SSDP_ADDRESS, SSDP_PORT))?;
//                 write_header(dst, "man", "\"ssdp:discover\"")?;
//                 write_header(dst, "mx", &max_wait.to_string())?;
//                 write_header(dst, "st", &target)?;
//                 maybe_write(dst, "user-agent", user_agent)?;
//                 maybe_write(dst, "tcpport.upnp.org", tcp_port)?;
//                 write_header(dst, "cpfn.upnp.org", &friendly_name)?;
//                 maybe_write(dst, "cpuuid.upnp.org", uuid)?;
//                 write!(dst, "\r\n")?;
//             }
//             _ => unimplemented!(),
//         }

//         Ok(())
//     }
// }

D yooper/src/rnsplit.rs => yooper/src/rnsplit.rs +0 -1
@@ 1,1 0,0 @@


R yooper/src/message.rs => yooper/src/ssdp/message.rs +2 -2
@@ 1,8 1,8 @@
mod codec;
pub(self) mod types;

use crate::{FromHeaders, FromPacket, ToHeaders, ToPacket};
pub use codec::SSDPMessageCodec;
use crate::ssdp::packet::{FromHeaders, FromPacket, ToHeaders, ToPacket};
pub use codec::Codec;

#[derive(ToHeaders, FromHeaders, Debug, PartialEq)]
pub struct MSearch {

R yooper/src/message/codec.rs => yooper/src/ssdp/message/codec.rs +13 -12
@@ 1,25 1,26 @@
use super::Message;
use crate::{Error, FromPacket, SSDPDecoder, SSDPEncoder, ToPacket};
use crate::Error;
use crate::ssdp::packet::{FromPacket, self, ToPacket};

use bytes::BytesMut;
use tokio_util::codec::{Decoder, Encoder};

#[derive(Default)]
pub struct SSDPMessageCodec {
    encoder: SSDPEncoder,
    decoder: SSDPDecoder,
pub struct Codec {
    encoder: packet::Encoder,
    decoder: packet::Decoder,
}

impl SSDPMessageCodec {
impl Codec {
    pub fn new() -> Self {
        SSDPMessageCodec {
            encoder: SSDPEncoder {},
            decoder: SSDPDecoder {},
        Codec {
            encoder: packet::Encoder {},
            decoder: packet::Decoder {},
        }
    }
}

impl Encoder<Message> for SSDPMessageCodec {
impl Encoder<Message> for Codec {
    type Error = Error;

    fn encode(&mut self, p: Message, dst: &mut BytesMut) -> Result<(), Self::Error> {


@@ 27,7 28,7 @@ impl Encoder<Message> for SSDPMessageCodec {
    }
}

impl Decoder for SSDPMessageCodec {
impl Decoder for Codec {
    type Item = Message;
    type Error = Error;



@@ 44,12 45,12 @@ impl Decoder for SSDPMessageCodec {
mod tests {
    use super::super::{types::Ext, SearchResponse};
    use super::*;
    use crate::tests::constants::*;
    use crate::ssdp::tests::constants::*;

    #[test]
    fn test_decode_ok() {
        let mut buf = BytesMut::from(SEARCH_RESPONSE_EXAMPLE);
        let mut decoder = SSDPMessageDecoder::default();
        let mut decoder = Codec::default();
        let message = Message::SearchResponse(SearchResponse {
            max_age: "max-age=1800".into(),
            date: Some("Mon, 25 May 2020 02:39:02 GMT".into()),

R yooper/src/message/tests.rs => yooper/src/ssdp/message/tests.rs +1 -1
@@ 1,5 1,5 @@
use super::*;
use crate::packet::{FromPacket, Packet, PacketType::*, ToPacket};
use crate::ssdp::packet::{FromPacket, Packet, PacketType::*, ToPacket};

fn available_packet() -> Packet {
    Packet::new_from_literal(

R yooper/src/message/types.rs => yooper/src/ssdp/message/types.rs +0 -0
A yooper/src/ssdp/mod.rs => yooper/src/ssdp/mod.rs +5 -0
@@ 0,0 1,5 @@
pub mod message;
pub mod packet;

#[cfg(test)]
pub mod tests;

R yooper/src/packet.rs => yooper/src/ssdp/packet.rs +4 -4
@@ 5,11 5,11 @@ use std::collections::HashMap;
use std::net::Ipv4Addr;
use std::str::FromStr;

use crate::errors::Error;
use crate::Error;

pub use decoder::SSDPDecoder;
pub use encoder::SSDPEncoder;
pub use yooper_derive::*;
pub use decoder::Decoder;
pub use encoder::Encoder;
pub use yooper_derive::{FromPacket, ToPacket, FromHeaders, ToHeaders};

pub(crate) const REQUEST_LINE_NOTIFY: &str = "NOTIFY * HTTP/1.1";
pub(crate) const REQUEST_LINE_M_SEARCH: &str = "M-SEARCH * HTTP/1.1";

R yooper/src/packet/decoder.rs => yooper/src/ssdp/packet/decoder.rs +9 -10
@@ 1,14 1,14 @@
use crate::errors::Error;
use bytes::BytesMut;
use std::collections::HashMap;
use tokio_util::codec::Decoder;
use tokio_util::codec;

use super::Packet;

#[derive(Default)]
pub struct SSDPDecoder {}
pub struct Decoder {}

impl Decoder for SSDPDecoder {
impl codec::Decoder for Decoder {
    type Item = Packet;
    type Error = Error;



@@ 56,16 56,15 @@ fn split_header(line: &str) -> Result<(String, String), Error> {

#[cfg(test)]
mod tests {
    use super::*;
    use crate::packet::PacketType;

    use crate::tests::constants::*;
    use tokio_util::codec::Decoder;
    use bytes::BytesMut;
    use crate::ssdp::{packet::{Packet, PacketType}, tests::constants::*};

    #[test]
    fn test_parse_notify() {
        let mut buf = BytesMut::from(NOTIFY_EXAMPLE);

        let decoded = SSDPDecoder {}.decode(&mut buf).unwrap().unwrap();
        let decoded = super::Decoder {}.decode(&mut buf).unwrap().unwrap();
        assert_eq!(
            decoded,
            Packet::new_from_literal(


@@ 85,7 84,7 @@ mod tests {
    #[test]
    fn test_parse_m_search() {
        let mut buf = BytesMut::from(M_SEARCH_EXAMPLE);
        let decoded = SSDPDecoder {}.decode(&mut buf).unwrap().unwrap();
        let decoded = super::Decoder {}.decode(&mut buf).unwrap().unwrap();

        assert_eq!(
            decoded,


@@ 105,7 104,7 @@ mod tests {
    #[test]
    fn test_parse_search_response() {
        let mut buf = BytesMut::from(SEARCH_RESPONSE_EXAMPLE);
        let decoded = SSDPDecoder {}.decode(&mut buf).unwrap().unwrap();
        let decoded = super::Decoder {}.decode(&mut buf).unwrap().unwrap();

        assert_eq!(
            decoded,

A yooper/src/ssdp/packet/encoder.rs => yooper/src/ssdp/packet/encoder.rs +24 -0
@@ 0,0 1,24 @@
use bytes::BytesMut;
use tokio_util::codec;

use super::Packet;
use crate::errors::Error;
use std::fmt::Write;

#[derive(Default)]
pub struct Encoder {}

impl codec::Encoder<Packet> for Encoder {
    type Error = Error;

    #[allow(clippy::write_with_newline)]
    fn encode(&mut self, p: Packet, dst: &mut BytesMut) -> Result<(), Self::Error> {
        write!(dst, "{}\r\n", p.typ.to_string())?;
        p.headers
            .iter()
            .map(|(k, v)| write!(dst, "{}: {}\r\n", k, v))
            .collect::<Result<(), std::fmt::Error>>()?;
        write!(dst, "\r\n")?;
        Ok(())
    }
}

R yooper/src/testdata/msearch.bin => yooper/src/ssdp/testdata/msearch.bin +0 -0
R yooper/src/testdata/notify.bin => yooper/src/ssdp/testdata/notify.bin +0 -0
R yooper/src/testdata/response.bin => yooper/src/ssdp/testdata/response.bin +0 -0
R yooper/src/tests.rs => yooper/src/ssdp/tests.rs +0 -0
M yooper_derive/src/from_packet.rs => yooper_derive/src/from_packet.rs +5 -5
@@ 35,7 35,7 @@ impl<'a> FromPacket<'a> {

        let MessageVariant { reqline, nts, .. } = &self.0;

        tokens.extend(quote! { packet.typ == crate::PacketType::#reqline});
        tokens.extend(quote! { packet.typ == crate::ssdp::packet::PacketType::#reqline});
        if let Some(nts) = nts {
            tokens.extend(quote! {
                && packet.headers.get("nts").map_or(false, |h| h == #nts )


@@ 126,9 126,9 @@ pub fn headers(input: DeriveInput) -> Result<TokenStream> {

    let tokens = quote! {
        #[automatically_derived]
        impl #impl_generics crate::FromHeaders for #name #ty_generics #where_clause {
        impl #impl_generics crate::ssdp::packet::FromHeaders for #name #ty_generics #where_clause {

            fn from_headers(headers: &crate::Headers) -> Result<Self, crate::errors::Error> {
            fn from_headers(headers: &crate::ssdp::packet::Headers) -> Result<Self, crate::Error> {
                #headers
            }
        }


@@ 145,8 145,8 @@ pub fn derive(input: DeriveInput) -> Result<TokenStream> {

    let tokens = quote! {
        #[automatically_derived]
        impl #impl_generics crate::FromPacket for #name #ty_generics #where_clause {
            fn from_packet(packet: &crate::Packet) -> Result<Self, crate::Error> {
        impl #impl_generics crate::ssdp::packet::FromPacket for #name #ty_generics #where_clause {
            fn from_packet(packet: &crate::ssdp::packet::Packet) -> Result<Self, crate::Error> {
                #(#variants)*;

                Err(crate::Error::UnknownPacket)

M yooper_derive/src/to_packet.rs => yooper_derive/src/to_packet.rs +6 -6
@@ 35,8 35,8 @@ impl<'a> ToTokens for ToPacket<'a> {
            #parent::#name ( field ) => {
                let mut headers = field.to_headers();
                #nts_header
                crate::Packet {
                    typ: crate::PacketType::#reqline,
                crate::ssdp::packet::Packet {
                    typ: crate::ssdp::packet::PacketType::#reqline,
                    headers,
                }
            }


@@ 102,8 102,8 @@ pub fn headers(input: DeriveInput) -> Result<TokenStream> {
    let name = input.ident;
    let tokens = quote! {
        #[automatically_derived]
        impl #impl_generics crate::ToHeaders for #name #ty_generics #where_clause {
            fn to_headers(&self) -> crate::Headers {
        impl #impl_generics crate::ssdp::packet::ToHeaders for #name #ty_generics #where_clause {
            fn to_headers(&self) -> crate::ssdp::packet::Headers {
                #headers
            }
        }


@@ 121,8 121,8 @@ pub fn derive(input: DeriveInput) -> Result<TokenStream> {

    let tokens = quote! {
        #[automatically_derived]
        impl #impl_generics crate::ToPacket for #name #ty_generics #where_clause {
            fn to_packet(&self) -> crate::Packet {
        impl #impl_generics crate::ssdp::packet::ToPacket for #name #ty_generics #where_clause {
            fn to_packet(&self) -> crate::ssdp::packet::Packet {
                match self {
                    #(#variants)*,