diff --git a/Cargo.lock b/Cargo.lock index e1c577c..ab205eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,6 +13,13 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "amqp_codegen" +version = "0.1.0" +dependencies = [ + "strong-xml", +] + [[package]] name = "amqp_transport" version = "0.1.0" @@ -88,6 +95,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "jetscii" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9447923c57a8a2d5c1b0875cdf96a6324275df728b498f2ede0e5cbde088a15" + [[package]] name = "lazy_static" version = "1.4.0" @@ -305,6 +318,30 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +[[package]] +name = "strong-xml" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d19fb3a618e2f1039e32317c9f525e6d45c55af704ec7c429aa74412419bebf" +dependencies = [ + "jetscii", + "lazy_static", + "memchr", + "strong-xml-derive", + "xmlparser", +] + +[[package]] +name = "strong-xml-derive" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c781f499321613b112be5d9338189ef1ed19689a01edd23d923ea57ad5c7e1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "syn" version = "1.0.86" @@ -478,3 +515,9 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "xmlparser" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "114ba2b24d2167ef6d67d7d04c8cc86522b87f490025f39f0303b7db5bf5e3d8" diff --git a/Cargo.toml b/Cargo.toml index c39f429..dc5878f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["./amqp_transport"] +members = ["./amqp_transport", "./amqp_codegen"] [package] name = "amqp" diff --git a/README.md b/README.md index b9f4683..661bfcc 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ # amqp -https://www.rabbitmq.com/resources/specs/amqp0-9-1.pdf \ No newline at end of file +https://www.rabbitmq.com/resources/specs/amqp0-9-1.pdf +https://www.rabbitmq.com/resources/specs/amqp-xml-doc0-9-1.pdf \ No newline at end of file diff --git a/amqp_codegen/Cargo.toml b/amqp_codegen/Cargo.toml new file mode 100644 index 0000000..55a4bf4 --- /dev/null +++ b/amqp_codegen/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "amqp_codegen" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +strong-xml = "0.6.3" diff --git a/amqp_codegen/amqp-0-9-1.xml b/amqp_codegen/amqp-0-9-1.xml new file mode 100644 index 0000000..f70584f --- /dev/null +++ b/amqp_codegen/amqp-0-9-1.xml @@ -0,0 +1,468 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/amqp_codegen/src/main.rs b/amqp_codegen/src/main.rs new file mode 100644 index 0000000..8da8e83 --- /dev/null +++ b/amqp_codegen/src/main.rs @@ -0,0 +1,80 @@ +use std::fs; +use strong_xml::{XmlError, XmlRead}; + +#[derive(Debug, XmlRead)] +#[xml(tag = "amqp")] +struct Amqp { + #[xml(child = "domain")] + domains: Vec, + #[xml(child = "class")] + classes: Vec, +} + +#[derive(Debug, XmlRead)] +#[xml(tag = "domain")] +struct Domain { + #[xml(attr = "name")] + name: String, + #[xml(attr = "type")] + kind: String, + #[xml(child = "assert")] + asserts: Vec, +} + +#[derive(Debug, XmlRead)] +#[xml(tag = "assert")] +struct Assert { + #[xml(attr = "check")] + check: String, +} + +#[derive(Debug, XmlRead)] +#[xml(tag = "class")] +struct Class { + #[xml(attr = "name")] + name: String, + #[xml(attr = "handler")] + handler: String, + #[xml(attr = "index")] + index: u16, + #[xml(child = "method")] + methods: Vec, +} + +#[derive(Debug, XmlRead)] +#[xml(tag = "method")] +struct Method { + #[xml(attr = "name")] + name: String, + #[xml(child = "field")] + fields: Vec, + #[xml(attr = "index")] + index: u16, +} + +#[derive(Debug, XmlRead)] +#[xml(tag = "field")] +struct Field { + #[xml(attr = "name")] + name: String, + #[xml(attr = "domain")] + domain: Option, + #[xml(child = "assert")] + asserts: Vec, +} + +fn main() { + let content = fs::read_to_string("./amqp-0-9-1.xml").unwrap(); + + let amqp: Result = Amqp::from_str(&content); + + match amqp { + Ok(amqp) => { + println!("{amqp:#?}"); + } + Err(err) => { + eprintln!("{err}"); + return; + } + } +} diff --git a/amqp_transport/src/classes/connection.rs b/amqp_transport/src/classes/connection.rs new file mode 100644 index 0000000..759cbe6 --- /dev/null +++ b/amqp_transport/src/classes/connection.rs @@ -0,0 +1,24 @@ +type Octet = u8; +type PeerProperties = (); +type LongStr = String; + +pub enum Connection { + Start { + version_major: Option, + version_minor: Option, + server_properties: PeerProperties, + mechanisms: LongStr, + locales: LongStr, + }, + StartOk, + Secure, + SecureOk, + Tune, + TuneOk, + Open, + OpenOk, + Close, + CloseOk, + Blocked, + Unblocked, +} diff --git a/amqp_transport/src/classes/mod.rs b/amqp_transport/src/classes/mod.rs new file mode 100644 index 0000000..6108355 --- /dev/null +++ b/amqp_transport/src/classes/mod.rs @@ -0,0 +1,7 @@ +mod connection; + +use crate::classes::connection::Connection; + +pub enum Class { + Connection(Connection), +} diff --git a/amqp_transport/src/connection.rs b/amqp_transport/src/connection.rs index 37bdc08..e79a21a 100644 --- a/amqp_transport/src/connection.rs +++ b/amqp_transport/src/connection.rs @@ -32,8 +32,8 @@ impl Connection { async fn negotiate_version(&mut self) -> Result<(), TransError> { const HEADER_SIZE: usize = 8; - const PROTOCOL_VERSION: &[u8] = &[0, 9, 1]; - const PROTOCOL_HEADER: &[u8] = b"AMQP\0\0\x09\x01"; + const SUPPORTED_PROTOCOL_VERSION: &[u8] = &[0, 9, 1]; + const OWN_PROTOCOL_HEADER: &[u8] = b"AMQP\0\0\x09\x01"; debug!("Negotiating version"); @@ -49,15 +49,15 @@ impl Connection { let version = &read_header_buf[5..8]; self.stream - .write_all(PROTOCOL_HEADER) + .write_all(OWN_PROTOCOL_HEADER) .await .context("write protocol header")?; - if &read_header_buf[0..5] == b"AMQP\0" && version == PROTOCOL_VERSION { + if &read_header_buf[0..5] == b"AMQP\0" && version == SUPPORTED_PROTOCOL_VERSION { debug!(?version, "Version negotiation successful"); Ok(()) } else { - debug!(?version, expected_version = ?PROTOCOL_VERSION, "Version negotiation failed, unsupported version"); + debug!(?version, expected_version = ?SUPPORTED_PROTOCOL_VERSION, "Version negotiation failed, unsupported version"); Err(ProtocolError::OtherCloseConnection.into()) } } diff --git a/amqp_transport/src/lib.rs b/amqp_transport/src/lib.rs index c4fa279..bae2e80 100644 --- a/amqp_transport/src/lib.rs +++ b/amqp_transport/src/lib.rs @@ -1,5 +1,6 @@ #![allow(dead_code)] +mod classes; mod connection; mod error; mod frame;