1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use std::error::Error;
use std::ptr;
use crate::bindings::*;
use libxml::tree::Document;
pub struct Stylesheet {
pub(crate) ptr: xsltStylesheetPtr,
}
struct TransformContext {
pub(crate) ptr: xsltTransformContextPtr,
}
impl Drop for TransformContext {
fn drop(&mut self) {
unsafe {
xsltFreeTransformContext(self.ptr);
}
}
}
impl Stylesheet {
pub(crate) fn ptr(&self) -> xsltStylesheetPtr {
self.ptr
}
pub(crate) fn ptr_mut(&mut self) -> xsltStylesheetPtr {
self.ptr
}
pub fn transform(&mut self, doc: &Document) -> Result<Document, Box<Error>> {
let ctxt = self.build_context(doc)?;
let xslt_params = ptr::null_mut();
let real_dom = unsafe {
xsltApplyStylesheetUser(
self.ptr_mut(),
doc.doc_ptr(),
xslt_params,
ptr::null_mut(),
ptr::null_mut(),
ctxt.ptr,
)
};
if real_dom.is_null() {
Err(From::from("Unknown error applying stylesheet"))
}
else {
Ok(Document::new_ptr(real_dom))
}
}
fn build_context(&mut self, doc: &Document) -> Result<TransformContext, &'static str> {
unsafe {
let ptr = xsltNewTransformContext(self.ptr(), doc.doc_ptr());
if ptr.is_null() {
Err("xsltNewTransformContext returned NULL")
} else {
Ok(TransformContext { ptr })
}
}
}
}