From 844f3a5d11e4360e9d6bdb79cfed49287aa8b14d Mon Sep 17 00:00:00 2001 From: cel 🌸 Date: Mon, 4 Mar 2024 16:14:28 +0000 Subject: initial commit --- src/element.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/error.rs | 1 + src/event.rs | 1 + src/lexer.rs | 9 +++++++++ src/lib.rs | 15 +++++++++++++++ src/parser.rs | 1 + src/reader.rs | 32 ++++++++++++++++++++++++++++++++ src/writer.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 161 insertions(+) create mode 100644 src/element.rs create mode 100644 src/error.rs create mode 100644 src/event.rs create mode 100644 src/lexer.rs create mode 100644 src/lib.rs create mode 100644 src/parser.rs create mode 100644 src/reader.rs create mode 100644 src/writer.rs (limited to 'src') diff --git a/src/element.rs b/src/element.rs new file mode 100644 index 0000000..3273ba0 --- /dev/null +++ b/src/element.rs @@ -0,0 +1,55 @@ +// elements resemble a final tree, including inherited namespace information + +use std::collections::HashMap; + +// when are namespaces names chosen then if they are automatically calculated +// namespaces are held by readers and writers. +pub struct Namespace { + prefix: Option, + namespace: String, +} + +// names are qualified, they contain the namespace +pub struct Name { + namespace: String, + name: String, +} + +pub enum Node { + Element(Element), + Text(String), +} + +// should this be a trait? +pub struct Element { + name: Name, + // namespace: (Name, String), // can't have this, must be external method that is called within the context of a reader/writer + // each element once created contains the qualified namespace information for that element + // the name contains the qualified namespace so this is unnecessary + // namespace: String, + // hashmap of explicit namespace declarations on the element itself only + // possibly not needed as can be calculated at write time depending on context and qualified namespace, and for reading, element validity and namespaces are kept track of by the reader. + // namespaces: HashMap, String>, + // attributes can be in a different namespace than the element. how to make sure they are valid? + // maybe include the namespace instead of or with the prefix + // you can calculate the prefix from the namespaced name and the current writer context + // you can validate the prefix and calculate the namespace from the current reader context + // this results in readers and writers being able to return qualification errors as they aren't able to create elements until every part is qualified. + attributes: HashMap, + children: Option>, +} + +// example of deriving an element: + +// #[derive(XMLWrite, XMLRead)] +// #[peanuts(namespace = "jabber:client", namespace:stream = "http://etherx.jabber.org/streams", name = "stream:stream")] +// pub struct Stream { +// from: JID, +// id: String, +// to: JID, +// version: String, +// #[peanuts(namespace = "http://www.w3.org/XML/1998/namespace")] +// lang: Lang, +// } + +// note: if an element name has a prefix all unprefixed attributes are qualified by the namespace of the prefix, so in this example from's Name's namespace would be "http://etherx.jabber.org/streams" diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..12fcaf2 --- /dev/null +++ b/src/error.rs @@ -0,0 +1 @@ +pub enum Error {} diff --git a/src/event.rs b/src/event.rs new file mode 100644 index 0000000..1eab55b --- /dev/null +++ b/src/event.rs @@ -0,0 +1 @@ +// tags, declaration, comments, text. individual bits and what they contain, e.g. tag contains attributes and namespace declarations, lang, ONLY within the tag diff --git a/src/lexer.rs b/src/lexer.rs new file mode 100644 index 0000000..abb5ebd --- /dev/null +++ b/src/lexer.rs @@ -0,0 +1,9 @@ +// lexer: tokenizes to bits like '<', ' { + stream: R, + // holds which tags we are in atm over depth + depth: Vec, + namespaces: Vec<(usize, Namespace)>, +} + +impl Reader { + pub async fn read(&self) -> Result, Error> {} + pub async fn read_start(&self) -> Result, Error> {} + pub async fn read_end(&self) -> Result<(), Error> {} +} + +impl Stream for Reader { + type Item = impl From; + + async fn poll_next( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + todo!() + } +} diff --git a/src/writer.rs b/src/writer.rs new file mode 100644 index 0000000..d7fc037 --- /dev/null +++ b/src/writer.rs @@ -0,0 +1,47 @@ +use futures::{AsyncWrite, Sink}; + +use crate::{ + element::{Element, Name, Namespace}, + error::Error, +}; + +pub struct Writer { + stream: W, + depth: Vec, + namespaces: Vec<(usize, Namespace)>, +} + +impl Writer { + pub async fn write(&self, element: impl Into) -> Result<(), Error> {} + pub async fn write_start(&self, element: impl Into) -> Result<(), Error> {} + pub async fn write_end(&self) -> Result<(), Error> {} +} + +impl> Sink for Writer { + type Error = Error; + + fn poll_ready( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + todo!() + } + + fn start_send(self: std::pin::Pin<&mut Self>, item: E) -> Result<(), Self::Error> { + todo!() + } + + fn poll_flush( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + todo!() + } + + fn poll_close( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + todo!() + } +} -- cgit