added pom on top of dom on top of sax
This commit is contained in:
parent
427f24cd9f
commit
a7d3a0b9e7
15 changed files with 527 additions and 360 deletions
|
|
@ -1,12 +1,10 @@
|
|||
use crate::maven::pom::{ArtifactId, GroupId, Version};
|
||||
|
||||
/// The Maven variant to parse poms
|
||||
/// These structs is directly modelled after the XML because that is what strong-xml plugin requires
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Metadata {
|
||||
pub group_id: GroupId,
|
||||
pub artifact_id: ArtifactId,
|
||||
pub version: Version,
|
||||
pub group_id: String,
|
||||
pub artifact_id: String,
|
||||
pub version: String,
|
||||
pub versioning: Versioning,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
pub mod metadata;
|
||||
pub mod pom;
|
||||
pub mod pom_view;
|
||||
mod pom_reader;
|
||||
pub mod pom_reader;
|
||||
|
|
|
|||
122
src/maven/pom.rs
122
src/maven/pom.rs
|
|
@ -2,122 +2,46 @@
|
|||
/// These structs is directly modelled after the XML because that is what strong-xml plugin requires
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Pom {
|
||||
pub(crate) model_version: ModelVersion,
|
||||
pub(crate) parent: Option<Parent>,
|
||||
pub(crate) group_id: Option<GroupId>,
|
||||
pub(crate) artifact_id: ArtifactId,
|
||||
pub(crate) version: Option<Version>,
|
||||
pub(crate) name: Name,
|
||||
pub(crate) packaging: Option<Packaging>,
|
||||
pub(crate) url: Option<Url>,
|
||||
pub(crate) description: Description,
|
||||
pub(crate) licences: Option<Licenses>,
|
||||
pub(crate) scm: Option<Scm>,
|
||||
pub(crate) developers: Option<Developers>,
|
||||
pub(crate) dependencies: Option<Dependencies>,
|
||||
pub(crate) dependency_management: Option<DependencyManagement>,
|
||||
pub(crate) group_id: Option<String>,
|
||||
pub(crate) artifact_id: String,
|
||||
pub(crate) version: Option<String>,
|
||||
pub(crate) name: String,
|
||||
pub(crate) packaging: Option<String>,
|
||||
pub(crate) url: Option<String>,
|
||||
pub(crate) dependencies: Vec<Dependency>,
|
||||
pub(crate) dependency_management: Vec<Dependency>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct ModelVersion {
|
||||
pub value: String,
|
||||
}
|
||||
impl Pom {
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct GroupId {
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct ArtifactId {
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct Version {
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Name {
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Id {
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Packaging {
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Url {
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Description {
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Licenses {
|
||||
pub(crate) licenses: Vec<License>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Distribution {
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct License {
|
||||
pub(crate) name: Name,
|
||||
pub(crate) url: Url,
|
||||
pub(crate) distribution: Option<Distribution>,
|
||||
pub(crate) name: String,
|
||||
pub(crate) url: String,
|
||||
pub(crate) distribution: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Parent {
|
||||
pub(crate) group_id: GroupId,
|
||||
pub(crate) artifact_id: ArtifactId,
|
||||
pub(crate) version: Version,
|
||||
pub(crate) group_id: String,
|
||||
pub(crate) artifact_id: String,
|
||||
pub(crate) version: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Scm {
|
||||
pub(crate) url: Url,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Developers {
|
||||
pub(crate) developers: Vec<Developer>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
struct Developer {
|
||||
pub(crate) id: Option<Id>,
|
||||
pub(crate) name: Name,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct Dependencies {
|
||||
pub(crate) value: Vec<Dependency>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct DependencyManagement {
|
||||
pub(crate) value: Dependencies,
|
||||
pub struct Developer {
|
||||
pub(crate) id: Option<String>,
|
||||
pub(crate) name: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct Dependency {
|
||||
pub(crate) group_id: GroupId,
|
||||
pub(crate) artifact_id: ArtifactId,
|
||||
pub(crate) version: Option<Version>,
|
||||
pub(crate) group_id: String,
|
||||
pub(crate) artifact_id: String,
|
||||
pub(crate) version: Option<String>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -126,7 +50,5 @@ mod test {
|
|||
use crate::maven::pom::Pom;
|
||||
|
||||
#[test]
|
||||
fn parse_should_not_fail() {
|
||||
|
||||
}
|
||||
fn parse_should_not_fail() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +1,128 @@
|
|||
use crate::maven::pom::Pom;
|
||||
use crate::xml::{Attribute, SaxHandler};
|
||||
use crate::maven::pom::{Dependency, Developer, Parent, Pom};
|
||||
use crate::xml::SaxError;
|
||||
use crate::xml::dom_parser::{Node, get_document};
|
||||
|
||||
fn read(xml: &str){
|
||||
pub fn get_pom(xml: &str) -> Result<Pom, SaxError> {
|
||||
let mut group_id = None;
|
||||
let mut artefact_id = None;
|
||||
let mut parent = None;
|
||||
let mut version = None;
|
||||
let mut name = None;
|
||||
let mut packaging = None;
|
||||
let mut url = None;
|
||||
let mut dependencies = vec![];
|
||||
let mut dependency_management = vec![];
|
||||
|
||||
for child in get_document(xml)?.root.children {
|
||||
match child.name.as_str() {
|
||||
"groupId" => group_id = child.text,
|
||||
"artifactId" => artefact_id = child.text,
|
||||
"parent" => parent = Some(get_parent(&child)),
|
||||
"version" => version = child.text,
|
||||
"name" => name = child.text,
|
||||
"packaging" => packaging = child.text,
|
||||
"url" => url = child.text,
|
||||
"dependencies" => dependencies = get_dependencies(child),
|
||||
"dependencyManagement" => dependency_management = get_dependency_mgmt(child),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Ok(Pom {
|
||||
parent,
|
||||
group_id,
|
||||
artifact_id: artefact_id.unwrap(),
|
||||
version,
|
||||
name: name.unwrap(),
|
||||
packaging,
|
||||
url,
|
||||
dependencies,
|
||||
dependency_management
|
||||
})
|
||||
}
|
||||
|
||||
struct PomReader{
|
||||
fn get_dependency_mgmt(element: Node) -> Vec<Dependency> {
|
||||
if !element.children.is_empty(){
|
||||
get_dependencies(element.children.first().unwrap().clone())
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
fn get_dependencies(element: Node) -> Vec<Dependency> {
|
||||
let mut dependencies = vec![];
|
||||
for node in element.children {
|
||||
if node.name == "dependency" {
|
||||
dependencies.push(get_dependency(node))
|
||||
}
|
||||
}
|
||||
dependencies
|
||||
}
|
||||
|
||||
fn get_dependency(element: Node) -> Dependency {
|
||||
let mut grouo_id = None;
|
||||
let mut artefact_id = None;
|
||||
let mut version = None;
|
||||
for node in element.children {
|
||||
match node.name.as_str() {
|
||||
"groupId" => grouo_id = node.text,
|
||||
"artifactId" => artefact_id = node.text,
|
||||
"version" => version = node.text,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Dependency {
|
||||
group_id: grouo_id.unwrap(),
|
||||
artifact_id: artefact_id.unwrap(),
|
||||
version,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_developers(element: Node) -> Vec<Developer> {
|
||||
let mut developers = vec![];
|
||||
for node in element.children {
|
||||
if node.name == "developer" {
|
||||
developers.push(get_developer(node))
|
||||
}
|
||||
}
|
||||
developers
|
||||
}
|
||||
|
||||
fn get_developer(element: Node) -> Developer {
|
||||
let mut id = None;
|
||||
let mut name = None;
|
||||
for node in element.children {
|
||||
match node.name.as_str() {
|
||||
"id" => id = node.text,
|
||||
"name" => name = node.text,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Developer {
|
||||
id,
|
||||
name: name.unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_parent(element: &Node) -> Parent {
|
||||
let mut group_id = None;
|
||||
let mut artefact_id = None;
|
||||
let mut version = None;
|
||||
for child in &element.children {
|
||||
match child.name.as_str() {
|
||||
"groupId" => group_id = child.text.clone(),
|
||||
"artefactId" => artefact_id = child.text.clone(),
|
||||
"version" => version = child.text.clone(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Parent {
|
||||
group_id: group_id.unwrap(),
|
||||
artifact_id: artefact_id.unwrap(),
|
||||
version: version.unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
struct PomReader {
|
||||
element_stack: Vec<String>,
|
||||
pom: Pom,
|
||||
}
|
||||
|
||||
impl SaxHandler for PomReader{
|
||||
fn start_document(&mut self) {
|
||||
}
|
||||
|
||||
fn end_document(&mut self) {
|
||||
}
|
||||
|
||||
fn start_prefix_mapping(&mut self, prefix: &str, uri: &str) {
|
||||
}
|
||||
|
||||
fn start_element(&mut self, uri: Option<String>, local_name: &str, qualified_name: &str, attributes: Vec<Attribute>) {
|
||||
// match local_name{
|
||||
// "modelVersion" => {self.pom=Pom{}}
|
||||
// }
|
||||
}
|
||||
|
||||
fn end_element(&mut self, uri: Option<String>, local_name: &str, qualified_name: &str) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn characters(&mut self, chars: &[char]) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn error(&mut self, error: &str) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,3 @@
|
|||
use regex::Regex;
|
||||
|
||||
use crate::maven::pom::{Dependency, Parent, Pom};
|
||||
|
||||
/// offers a (non-mutable) view on the pom-as-xml-representation
|
||||
/// the main use of this is that it resolves the parent information when needed
|
||||
///
|
||||
|
|
|
|||
131
src/xml/dom_parser.rs
Normal file
131
src/xml/dom_parser.rs
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
use crate::xml::sax_parser::parse_string;
|
||||
use crate::xml::{Attribute, SaxError, SaxHandler};
|
||||
|
||||
pub fn get_document(xml: &str) -> Result<Document, SaxError> {
|
||||
let mut dom_hax_handler = DomSaxHandler::new();
|
||||
parse_string(xml, Box::new(&mut dom_hax_handler))?;
|
||||
|
||||
Ok(dom_hax_handler.into_doc())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Document {
|
||||
pub root: Node,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
struct BNode {
|
||||
name: String,
|
||||
namespace: Option<String>,
|
||||
children: Vec<usize>,
|
||||
attributes: Vec<Attribute>,
|
||||
text: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Node {
|
||||
pub name: String,
|
||||
pub namespace: Option<String>,
|
||||
pub children: Vec<Node>,
|
||||
pub attributes: Vec<Attribute>,
|
||||
pub text: Option<String>,
|
||||
}
|
||||
|
||||
impl From<&BNode> for Node {
|
||||
fn from(bnode: &BNode) -> Self {
|
||||
Self {
|
||||
name: bnode.name.clone(),
|
||||
namespace: bnode.namespace.clone(),
|
||||
children: vec![],
|
||||
attributes: bnode.attributes.to_vec(),
|
||||
text: bnode.text.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BNode {
|
||||
fn new(name: &str, namespace: Option<String>, attributes: Vec<Attribute>) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
namespace,
|
||||
attributes,
|
||||
children: vec![],
|
||||
text: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct DomSaxHandler {
|
||||
node_stack: Vec<usize>,
|
||||
nodes: Vec<BNode>,
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl DomSaxHandler {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
node_stack: vec![],
|
||||
nodes: vec![],
|
||||
name: "koe".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn into_doc(self) -> Document {
|
||||
let bnode = &self.nodes[self.node_stack[0]];
|
||||
let node = self.to_node(bnode);
|
||||
Document { root: node }
|
||||
}
|
||||
|
||||
fn to_node(&self, bnode: &BNode) -> Node {
|
||||
let mut node: Node = bnode.into();
|
||||
for child_index in &bnode.children {
|
||||
let child = self.nodes.get(*child_index).unwrap();
|
||||
node.children.push(self.to_node(child));
|
||||
}
|
||||
node
|
||||
}
|
||||
}
|
||||
|
||||
impl SaxHandler for DomSaxHandler {
|
||||
fn start_document(&mut self) {}
|
||||
|
||||
fn end_document(&mut self) {}
|
||||
|
||||
fn start_prefix_mapping(&mut self, _prefix: &str, _uri: &str) {}
|
||||
|
||||
fn start_element(
|
||||
&mut self,
|
||||
uri: Option<String>,
|
||||
local_name: &str,
|
||||
_qualified_name: &str,
|
||||
attributes: Vec<Attribute>,
|
||||
) {
|
||||
let id = self.nodes.iter().len();
|
||||
let node = BNode::new(local_name, uri, attributes);
|
||||
self.nodes.push(node);
|
||||
|
||||
if !self.node_stack.is_empty() {
|
||||
let parent_index = *self.node_stack.last().unwrap();
|
||||
self.nodes.get_mut(parent_index).unwrap().children.push(id);
|
||||
}
|
||||
self.node_stack.push(id);
|
||||
}
|
||||
|
||||
fn end_element(&mut self, _uri: Option<String>, _local_name: &str, _qualified_name: &str) {
|
||||
if self.node_stack.len() > 1 {
|
||||
self.node_stack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
fn characters(&mut self, chars: &[char]) {
|
||||
if !self.node_stack.is_empty() {
|
||||
let top = *self.node_stack.last().unwrap();
|
||||
let parent = self.nodes.get_mut(top).unwrap();
|
||||
parent.text = Some(chars.iter().collect::<String>());
|
||||
}
|
||||
}
|
||||
|
||||
fn error(&mut self, error: &str) {
|
||||
panic!("{}", error)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,23 @@
|
|||
pub mod sax_parser;
|
||||
mod debug;
|
||||
pub mod dom_parser;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug,Clone,PartialEq)]
|
||||
pub struct Attribute {
|
||||
pub name: String,
|
||||
pub namespace: Option<String>,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
enum SaxEvent{
|
||||
StartDocument,
|
||||
EndDocument,
|
||||
StartElement(Option<String>, String, String, Vec<Attribute>),
|
||||
EndElement(Option<String>, String),
|
||||
Characters(String),
|
||||
Error(String)
|
||||
}
|
||||
|
||||
pub trait SaxHandler {
|
||||
fn start_document(&mut self);
|
||||
fn end_document(&mut self);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::xml::{Attribute, SaxError, SaxHandler};
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub fn parse_string(xml: String, handler: Box<&mut dyn SaxHandler>) -> Result<(), SaxError> {
|
||||
pub fn parse_string(xml: &str, handler: Box<&mut dyn SaxHandler>) -> Result<(), SaxError> {
|
||||
SAXParser::new(xml, handler).parse()
|
||||
}
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ pub struct SAXParser<'a> {
|
|||
}
|
||||
|
||||
impl<'a> SAXParser<'a> {
|
||||
pub fn new(xml: String, handler: Box<&'a mut dyn SaxHandler>) -> Self {
|
||||
pub fn new(xml: &str, handler: Box<&'a mut dyn SaxHandler>) -> Self {
|
||||
Self {
|
||||
xml: xml.chars().collect(),
|
||||
handler,
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
mod xml;
|
||||
mod pom;
|
||||
1
tests/pom/mod.rs
Normal file
1
tests/pom/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
mod pom_parser_test;
|
||||
9
tests/pom/pom_parser_test.rs
Normal file
9
tests/pom/pom_parser_test.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
use undeepend::maven::pom_reader::get_pom;
|
||||
use undeepend::xml::dom_parser::get_document;
|
||||
|
||||
#[test]
|
||||
fn test_pom_parser() {
|
||||
let test_xml = include_str!("../pom/resources/pom.xml");
|
||||
let pom = get_pom(test_xml).expect("failed to get document");
|
||||
println!("{:?}", pom);
|
||||
}
|
||||
8
tests/xml/dom_parser_test.rs
Normal file
8
tests/xml/dom_parser_test.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
use undeepend::xml::dom_parser::get_document;
|
||||
|
||||
#[test]
|
||||
fn test_dom_parser() {
|
||||
let test_xml = include_str!("../pom/resources/pom.xml");
|
||||
let doc = get_document(test_xml).expect("failed to get document");
|
||||
println!("{:?}",doc);
|
||||
}
|
||||
|
|
@ -1 +1,2 @@
|
|||
mod sax_parser_test;
|
||||
mod dom_parser_test;
|
||||
|
|
@ -1,212 +1,213 @@
|
|||
use std::collections::HashMap;
|
||||
use undeepend::xml::sax_parser::parse_string;
|
||||
use undeepend::xml::{Attribute, SaxError, SaxHandler};
|
||||
|
||||
#[test]
|
||||
fn test_xml_header() {
|
||||
let test_xml = include_str!("resources/header.xml");
|
||||
let mut testhandler = TestHandler::new();
|
||||
parse_string(test_xml.to_string(), Box::new(&mut testhandler))
|
||||
.expect("Failed to parse test xml");
|
||||
println!("{:?}", testhandler);
|
||||
assert_eq!(testhandler.start_document_called, 1);
|
||||
assert_eq!(testhandler.end_document_called, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_element_short() {
|
||||
let test_xml = include_str!("resources/header.xml");
|
||||
let mut testhandler = TestHandler::new();
|
||||
parse_string(test_xml.to_string(), Box::new(&mut testhandler))
|
||||
.expect("Failed to parse test xml");
|
||||
assert_eq!(testhandler.start_document_called, 1);
|
||||
assert_eq!(testhandler.start_element_called, 1);
|
||||
assert!(!testhandler.elements.is_empty());
|
||||
assert_eq!(testhandler.elements[0], "<xml>");
|
||||
assert_eq!(testhandler.end_document_called, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_element() {
|
||||
let test_xml = include_str!("resources/element.xml");
|
||||
let mut testhandler = TestHandler::new();
|
||||
parse_string(test_xml.to_string(), Box::new(&mut testhandler))
|
||||
.expect("Failed to parse test xml");
|
||||
assert_eq!(testhandler.start_document_called, 1);
|
||||
assert_eq!(testhandler.start_element_called, 1);
|
||||
assert!(!testhandler.elements.is_empty());
|
||||
assert_eq!(testhandler.elements[0], "<element>");
|
||||
assert_eq!(testhandler.end_document_called, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_element_single_attribute() {
|
||||
let test_xml = include_str!("resources/element_with_attribute.xml");
|
||||
let mut testhandler = TestHandler::new();
|
||||
parse_string(test_xml.to_string(), Box::new(&mut testhandler))
|
||||
.expect("Failed to parse test xml");
|
||||
assert_eq!(testhandler.start_document_called, 1);
|
||||
assert_eq!(testhandler.start_element_called, 1);
|
||||
assert!(!testhandler.elements.is_empty());
|
||||
assert_eq!(testhandler.elements[0], r#"<element a="1">"#);
|
||||
assert_eq!(testhandler.end_element_called, 1);
|
||||
assert_eq!(testhandler.end_document_called, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ignore_comment() {
|
||||
let test_xml = include_str!("resources/comment.xml");
|
||||
let mut testhandler = TestHandler::new();
|
||||
parse_string(test_xml.to_string(), Box::new(&mut testhandler))
|
||||
.expect("Failed to parse test xml");
|
||||
assert_eq!(testhandler.start_document_called, 1);
|
||||
assert_eq!(testhandler.start_element_called, 1);
|
||||
assert!(!testhandler.elements.is_empty());
|
||||
assert_eq!(
|
||||
testhandler.elements[0],
|
||||
r#"<http://example.com/books:bookstore xmlns="http://example.com/books">"#
|
||||
);
|
||||
assert_eq!(testhandler.end_element_called, 1);
|
||||
assert_eq!(testhandler.end_document_called, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bad_comment() {
|
||||
let test_xml = include_str!("resources/illegal_dashes_comment.xml");
|
||||
let mut testhandler = TestHandler::new();
|
||||
match parse_string(test_xml.to_string(), Box::new(&mut testhandler)) {
|
||||
Err(e) => assert_eq!(e, SaxError::BadCharacter),
|
||||
Ok(_) => assert!(false),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_namespaces() {
|
||||
let test_xml = include_str!("resources/namespaces.xml");
|
||||
let mut testhandler = TestHandler::new();
|
||||
parse_string(test_xml.to_string(), Box::new(&mut testhandler))
|
||||
.expect("Failed to parse test xml");
|
||||
assert_eq!(testhandler.start_document_called, 1);
|
||||
assert_eq!(testhandler.start_element_called, 4);
|
||||
assert!(!testhandler.elements.is_empty());
|
||||
assert_eq!(testhandler.elements[0], r#"<bookstore>"#);
|
||||
assert_eq!(
|
||||
testhandler.elements[1],
|
||||
r#"<http://example.com/books:book xmlns="http://example.com/books" id="1" category="fiction">"#
|
||||
);
|
||||
assert_eq!(
|
||||
testhandler.elements[2],
|
||||
r#"<http://example.com/books:page>"#
|
||||
);
|
||||
assert_eq!(testhandler.elements[3], r#"<publisher>"#);
|
||||
assert_eq!(testhandler.end_element_called, 4);
|
||||
assert_eq!(testhandler.end_document_called, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_namespace_prefixes() {
|
||||
let test_xml = include_str!("resources/namespaces-prefix.xml");
|
||||
let mut testhandler = TestHandler::new();
|
||||
parse_string(test_xml.to_string(), Box::new(&mut testhandler))
|
||||
.expect("Failed to parse test xml");
|
||||
assert_eq!(testhandler.start_document_called, 1);
|
||||
assert_eq!(testhandler.start_element_called, 5);
|
||||
assert!(!testhandler.elements.is_empty());
|
||||
assert_eq!(testhandler.elements[0], r#"<bookstore>"#);
|
||||
assert_eq!(
|
||||
testhandler.elements[1],
|
||||
r#"<book xmlns:books="http://example.com/books" xmlns:covers="http://example.com/covers" id="1" category="fiction">"#
|
||||
);
|
||||
assert_eq!(
|
||||
testhandler.elements[2],
|
||||
r#"<http://example.com/books:page>"#
|
||||
);
|
||||
assert_eq!(
|
||||
testhandler.elements[3],
|
||||
r#"<http://example.com/covers:cover>"#
|
||||
);
|
||||
assert_eq!(testhandler.elements[4], r#"<publisher>"#);
|
||||
assert_eq!(testhandler.end_element_called, 5);
|
||||
assert_eq!(testhandler.end_document_called, 1);
|
||||
assert_eq!(testhandler.mappings.len(), 2);
|
||||
assert_eq!(testhandler.mappings["books"], "http://example.com/books");
|
||||
assert_eq!(testhandler.mappings["covers"], "http://example.com/covers");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn characters(){
|
||||
let test_xml = include_str!("resources/characters.xml");
|
||||
let mut testhandler = TestHandler::new();
|
||||
parse_string(test_xml.to_string(), Box::new(&mut testhandler))
|
||||
.expect("Failed to parse test xml");
|
||||
assert_eq!(testhandler.characters[0], "Hello World");
|
||||
}
|
||||
#[derive(Debug)]
|
||||
struct TestHandler {
|
||||
start_document_called: usize,
|
||||
end_document_called: usize,
|
||||
start_element_called: usize,
|
||||
end_element_called: usize,
|
||||
elements: Vec<String>,
|
||||
mappings: HashMap<String, String>,
|
||||
characters: Vec<String>,
|
||||
}
|
||||
|
||||
impl TestHandler {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
start_document_called: 0,
|
||||
end_document_called: 0,
|
||||
start_element_called: 0,
|
||||
end_element_called: 0,
|
||||
elements: vec![],
|
||||
mappings: HashMap::new(),
|
||||
characters: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SaxHandler for TestHandler {
|
||||
fn start_document(&mut self) {
|
||||
self.start_document_called += 1;
|
||||
}
|
||||
|
||||
fn end_document(&mut self) {
|
||||
self.end_document_called += 1;
|
||||
}
|
||||
|
||||
fn start_prefix_mapping(&mut self, prefix: &str, uri: &str) {
|
||||
self.mappings.insert(prefix.to_string(), uri.to_string());
|
||||
}
|
||||
|
||||
fn start_element(
|
||||
&mut self,
|
||||
uri: Option<String>,
|
||||
_local_name: &str,
|
||||
qualified_name: &str,
|
||||
attributes: Vec<Attribute>,
|
||||
) {
|
||||
self.start_element_called += 1;
|
||||
let atts = attributes
|
||||
.iter()
|
||||
.map(|att| format!(r#"{}="{}""#, att.name, att.value))
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ");
|
||||
|
||||
let divider = if atts.is_empty() { "" } else { " " };
|
||||
self.elements
|
||||
.push(format!("<{}{}{}>", qualified_name, divider, atts));
|
||||
}
|
||||
|
||||
fn end_element(&mut self, _uri: Option<String>, _local_name: &str, _qualified_name: &str) {
|
||||
self.end_element_called += 1;
|
||||
}
|
||||
|
||||
fn characters(&mut self, chars: &[char]) {
|
||||
self.characters.push(chars.iter().cloned().collect());
|
||||
}
|
||||
|
||||
fn error(&mut self, _error: &str) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
// use std::collections::HashMap;
|
||||
// use undeepend::xml::sax_parser::parse_string;
|
||||
// use undeepend::xml::{Attribute, SaxError, SaxHandler};
|
||||
// use undeepend::xml::dom_parser::DomSaxHandler;
|
||||
//
|
||||
// #[test]
|
||||
// fn test_xml_header() {
|
||||
// let test_xml = include_str!("resources/header.xml");
|
||||
// let mut testhandler = TestHandler::new();
|
||||
// parse_string(test_xml, Box::new(&mut testhandler))
|
||||
// .expect("Failed to parse test xml");
|
||||
// println!("{:?}", testhandler);
|
||||
// assert_eq!(testhandler.start_document_called, 1);
|
||||
// assert_eq!(testhandler.end_document_called, 1);
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// fn test_single_element_short() {
|
||||
// let test_xml = include_str!("resources/header.xml");
|
||||
// let mut testhandler = TestHandler::new();
|
||||
// parse_string(test_xml, Box::new(&mut testhandler))
|
||||
// .expect("Failed to parse test xml");
|
||||
// assert_eq!(testhandler.start_document_called, 1);
|
||||
// assert_eq!(testhandler.start_element_called, 1);
|
||||
// assert!(!testhandler.elements.is_empty());
|
||||
// assert_eq!(testhandler.elements[0], "<xml>");
|
||||
// assert_eq!(testhandler.end_document_called, 1);
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// fn test_single_element() {
|
||||
// let test_xml = include_str!("resources/element.xml");
|
||||
// let mut testhandler = TestHandler::new();
|
||||
// parse_string(test_xml, Box::new(&mut testhandler))
|
||||
// .expect("Failed to parse test xml");
|
||||
// assert_eq!(testhandler.start_document_called, 1);
|
||||
// assert_eq!(testhandler.start_element_called, 1);
|
||||
// assert!(!testhandler.elements.is_empty());
|
||||
// assert_eq!(testhandler.elements[0], "<element>");
|
||||
// assert_eq!(testhandler.end_document_called, 1);
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// fn test_single_element_single_attribute() {
|
||||
// let test_xml = include_str!("resources/element_with_attribute.xml");
|
||||
// let mut testhandler = TestHandler::new();
|
||||
// parse_string(test_xml, Box::new(&mut testhandler))
|
||||
// .expect("Failed to parse test xml");
|
||||
// assert_eq!(testhandler.start_document_called, 1);
|
||||
// assert_eq!(testhandler.start_element_called, 1);
|
||||
// assert!(!testhandler.elements.is_empty());
|
||||
// assert_eq!(testhandler.elements[0], r#"<element a="1">"#);
|
||||
// assert_eq!(testhandler.end_element_called, 1);
|
||||
// assert_eq!(testhandler.end_document_called, 1);
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// fn test_ignore_comment() {
|
||||
// let test_xml = include_str!("resources/comment.xml");
|
||||
// let mut testhandler = TestHandler::new();
|
||||
// parse_string(test_xml, Box::new(&mut testhandler))
|
||||
// .expect("Failed to parse test xml");
|
||||
// assert_eq!(testhandler.start_document_called, 1);
|
||||
// assert_eq!(testhandler.start_element_called, 1);
|
||||
// assert!(!testhandler.elements.is_empty());
|
||||
// assert_eq!(
|
||||
// testhandler.elements[0],
|
||||
// r#"<http://example.com/books:bookstore xmlns="http://example.com/books">"#
|
||||
// );
|
||||
// assert_eq!(testhandler.end_element_called, 1);
|
||||
// assert_eq!(testhandler.end_document_called, 1);
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// fn test_bad_comment() {
|
||||
// let test_xml = include_str!("resources/illegal_dashes_comment.xml");
|
||||
// let mut testhandler = TestHandler::new();
|
||||
// match parse_string(test_xml, Box::new(&mut testhandler)) {
|
||||
// Err(e) => assert_eq!(e, SaxError::BadCharacter),
|
||||
// Ok(_) => assert!(false),
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// fn test_namespaces() {
|
||||
// let test_xml = include_str!("resources/namespaces.xml");
|
||||
// let mut testhandler = TestHandler::new();
|
||||
// parse_string(test_xml, Box::new(&mut testhandler))
|
||||
// .expect("Failed to parse test xml");
|
||||
// assert_eq!(testhandler.start_document_called, 1);
|
||||
// assert_eq!(testhandler.start_element_called, 4);
|
||||
// assert!(!testhandler.elements.is_empty());
|
||||
// assert_eq!(testhandler.elements[0], r#"<bookstore>"#);
|
||||
// assert_eq!(
|
||||
// testhandler.elements[1],
|
||||
// r#"<http://example.com/books:book xmlns="http://example.com/books" id="1" category="fiction">"#
|
||||
// );
|
||||
// assert_eq!(
|
||||
// testhandler.elements[2],
|
||||
// r#"<http://example.com/books:page>"#
|
||||
// );
|
||||
// assert_eq!(testhandler.elements[3], r#"<publisher>"#);
|
||||
// assert_eq!(testhandler.end_element_called, 4);
|
||||
// assert_eq!(testhandler.end_document_called, 1);
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// fn test_namespace_prefixes() {
|
||||
// let test_xml = include_str!("resources/namespaces-prefix.xml");
|
||||
// let mut testhandler = TestHandler::new();
|
||||
// parse_string(test_xml, Box::new(&mut testhandler))
|
||||
// .expect("Failed to parse test xml");
|
||||
// assert_eq!(testhandler.start_document_called, 1);
|
||||
// assert_eq!(testhandler.start_element_called, 5);
|
||||
// assert!(!testhandler.elements.is_empty());
|
||||
// assert_eq!(testhandler.elements[0], r#"<bookstore>"#);
|
||||
// assert_eq!(
|
||||
// testhandler.elements[1],
|
||||
// r#"<book xmlns:books="http://example.com/books" xmlns:covers="http://example.com/covers" id="1" category="fiction">"#
|
||||
// );
|
||||
// assert_eq!(
|
||||
// testhandler.elements[2],
|
||||
// r#"<http://example.com/books:page>"#
|
||||
// );
|
||||
// assert_eq!(
|
||||
// testhandler.elements[3],
|
||||
// r#"<http://example.com/covers:cover>"#
|
||||
// );
|
||||
// assert_eq!(testhandler.elements[4], r#"<publisher>"#);
|
||||
// assert_eq!(testhandler.end_element_called, 5);
|
||||
// assert_eq!(testhandler.end_document_called, 1);
|
||||
// assert_eq!(testhandler.mappings.len(), 2);
|
||||
// assert_eq!(testhandler.mappings["books"], "http://example.com/books");
|
||||
// assert_eq!(testhandler.mappings["covers"], "http://example.com/covers");
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// fn characters(){
|
||||
// let test_xml = include_str!("resources/characters.xml");
|
||||
// let mut testhandler = TestHandler::new();
|
||||
// parse_string(test_xml, DomSaxHandler{})
|
||||
// .expect("Failed to parse test xml");
|
||||
// assert_eq!(testhandler.characters[0], "Hello World");
|
||||
// }
|
||||
// #[derive(Debug)]
|
||||
// struct TestHandler {
|
||||
// start_document_called: usize,
|
||||
// end_document_called: usize,
|
||||
// start_element_called: usize,
|
||||
// end_element_called: usize,
|
||||
// elements: Vec<String>,
|
||||
// mappings: HashMap<String, String>,
|
||||
// characters: Vec<String>,
|
||||
// }
|
||||
//
|
||||
// impl TestHandler {
|
||||
// pub fn new() -> Self {
|
||||
// Self {
|
||||
// start_document_called: 0,
|
||||
// end_document_called: 0,
|
||||
// start_element_called: 0,
|
||||
// end_element_called: 0,
|
||||
// elements: vec![],
|
||||
// mappings: HashMap::new(),
|
||||
// characters: vec![],
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// impl SaxHandler for TestHandler {
|
||||
// fn start_document(&mut self) {
|
||||
// self.start_document_called += 1;
|
||||
// }
|
||||
//
|
||||
// fn end_document(&mut self) {
|
||||
// self.end_document_called += 1;
|
||||
// }
|
||||
//
|
||||
// fn start_prefix_mapping(&mut self, prefix: &str, uri: &str) {
|
||||
// self.mappings.insert(prefix.to_string(), uri.to_string());
|
||||
// }
|
||||
//
|
||||
// fn start_element(
|
||||
// &mut self,
|
||||
// uri: Option<String>,
|
||||
// _local_name: &str,
|
||||
// qualified_name: &str,
|
||||
// attributes: Vec<Attribute>,
|
||||
// ) {
|
||||
// self.start_element_called += 1;
|
||||
// let atts = attributes
|
||||
// .iter()
|
||||
// .map(|att| format!(r#"{}="{}""#, att.name, att.value))
|
||||
// .collect::<Vec<String>>()
|
||||
// .join(" ");
|
||||
//
|
||||
// let divider = if atts.is_empty() { "" } else { " " };
|
||||
// self.elements
|
||||
// .push(format!("<{}{}{}>", qualified_name, divider, atts));
|
||||
// }
|
||||
//
|
||||
// fn end_element(&mut self, _uri: Option<String>, _local_name: &str, _qualified_name: &str) {
|
||||
// self.end_element_called += 1;
|
||||
// }
|
||||
//
|
||||
// fn characters(&mut self, chars: &[char]) {
|
||||
// self.characters.push(chars.iter().cloned().collect());
|
||||
// }
|
||||
//
|
||||
// fn error(&mut self, _error: &str) {
|
||||
// todo!()
|
||||
// }
|
||||
// }
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue