Skip to content

Commit 6de9e1a

Browse files
committed
Somewhat of inheritance
1 parent 5dd8a94 commit 6de9e1a

File tree

8 files changed

+153
-106
lines changed

8 files changed

+153
-106
lines changed

lolhtml.pyi

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class Doctype:
5656

5757
class DocumentEnd:
5858
def append(
59-
self, content: str, content_type: Optional[ContentType] = ...
59+
self, content: str, content_type: Optional[ContentType] = None
6060
) -> None: ...
6161

6262
class Element:
@@ -69,14 +69,12 @@ class Element:
6969
def remove(self) -> None: ...
7070
@property
7171
def namespace_uri(self) -> str: ...
72-
7372
@property
7473
def attributes(self) -> List[Tuple[str, str]]: ...
7574
def get_attribute(self, name: str) -> Optional[str]: ...
7675
def has_attribute(self, name: str) -> bool: ...
7776
def set_attribute(self, name: str, value: str) -> None: ...
7877
def remove_attribute(self, name: str) -> None: ...
79-
8078
def prepend(
8179
self, content: str, content_type: Optional[ContentType] = None
8280
) -> None: ...
@@ -113,21 +111,21 @@ class TextChunk:
113111
@property
114112
def last_in_text_node(self) -> bool: ...
115113
def before(
116-
self, content: str, content_type: Optional[ContentType] = ...
114+
self, content: str, content_type: Optional[ContentType] = None
117115
) -> None: ...
118116
def after(
119-
self, content: str, content_type: Optional[ContentType] = ...
117+
self, content: str, content_type: Optional[ContentType] = None
120118
) -> None: ...
121119
def replace(
122-
self, content: str, content_type: Optional[ContentType] = ...
120+
self, content: str, content_type: Optional[ContentType] = None
123121
) -> None: ...
124122
def remove(self) -> None: ...
125123
@property
126124
def removed(self) -> bool: ...
127125

128126
class HTMLRewriterOptions:
129127
enable_esi_tags: Optional[bool]
130-
def __init__(self, enable_esi_tags: Optional[bool] = ...) -> None: ...
128+
def __init__(self, enable_esi_tags: Optional[bool] = None) -> None: ...
131129

132130
class HTMLRewriter:
133131
def __init__(

src/comment.rs

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use lol_html::html_content::Comment as NativeComment;
2+
use lol_html::html_content::ContentType as NativeContentType;
23
use pyo3::prelude::*;
34

4-
use crate::{ContentType, NativeRefWrap, IntoNative};
5+
use crate::{ContentType, HasInner, NativeBeforeAfter, NativeRefWrap, PyBeforeAfter};
56

67
#[pyclass(unsendable)]
78
pub struct Comment {
@@ -16,6 +17,24 @@ impl Comment {
1617
}
1718
}
1819

20+
impl HasInner<NativeComment<'static>> for Comment {
21+
#[inline]
22+
fn inner_native(&mut self) -> &mut NativeRefWrap<NativeComment<'static>> {
23+
&mut self.inner
24+
}
25+
}
26+
27+
impl NativeBeforeAfter for lol_html::html_content::Comment<'static> {
28+
#[inline]
29+
fn native_before(&mut self, content: &str, ct: NativeContentType) {
30+
self.before(content, ct);
31+
}
32+
#[inline]
33+
fn native_after(&mut self, content: &str, ct: NativeContentType) {
34+
self.after(content, ct);
35+
}
36+
}
37+
1938
#[pymethods]
2039
impl Comment {
2140
#[getter]
@@ -46,27 +65,13 @@ impl Comment {
4665
}
4766

4867
#[pyo3(signature = (content, content_type=None))]
49-
pub fn before(
50-
&mut self,
51-
content: &str,
52-
content_type: Option<ContentType>,
53-
) -> PyResult<()> {
54-
self.inner
55-
.get_mut()?
56-
.before(content, content_type.into_native());
57-
Ok(())
68+
pub fn before(&mut self, content: &str, content_type: Option<ContentType>) -> PyResult<()> {
69+
<Self as PyBeforeAfter<NativeComment<'static>>>::before_impl(self, content, content_type)
5870
}
5971

6072
#[pyo3(signature = (content, content_type=None))]
61-
pub fn after(
62-
&mut self,
63-
content: &str,
64-
content_type: Option<ContentType>,
65-
) -> PyResult<()> {
66-
self.inner
67-
.get_mut()?
68-
.after(content, content_type.into_native());
69-
Ok(())
73+
pub fn after(&mut self, content: &str, content_type: Option<ContentType>) -> PyResult<()> {
74+
<Self as PyBeforeAfter<NativeComment<'static>>>::after_impl(self, content, content_type)
7075
}
7176

7277
pub fn __repr__(&self) -> PyResult<String> {

src/document_end.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,7 @@ impl DocumentEnd {
1818
#[pymethods]
1919
impl DocumentEnd {
2020
#[pyo3(signature = (content, content_type=None))]
21-
pub fn append(
22-
&mut self,
23-
content: &str,
24-
content_type: Option<ContentType>,
25-
) -> PyResult<()> {
21+
pub fn append(&mut self, content: &str, content_type: Option<ContentType>) -> PyResult<()> {
2622
self.inner
2723
.get_mut()?
2824
.append(content, content_type.into_native());

src/element.rs

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
use lol_html::html_content::ContentType as NativeContentType;
12
use lol_html::html_content::Element as NativeElement;
3+
24
use pyo3::exceptions::PyRuntimeError;
35
use pyo3::prelude::*;
46

5-
use crate::{ContentType, HasNative, IntoNative, NativeRefWrap};
7+
use crate::{
8+
ContentType, HasInner, HasNative, IntoNative, NativeBeforeAfter, NativeRefWrap, PyBeforeAfter,
9+
};
610

711
#[pyclass(unsendable)]
812
pub struct Element {
@@ -21,6 +25,24 @@ impl Element {
2125
}
2226
}
2327

28+
impl HasInner<NativeElement<'static, 'static>> for Element {
29+
#[inline]
30+
fn inner_native(&mut self) -> &mut NativeRefWrap<NativeElement<'static, 'static>> {
31+
&mut self.inner
32+
}
33+
}
34+
35+
impl NativeBeforeAfter for lol_html::html_content::Element<'static, 'static> {
36+
#[inline]
37+
fn native_before(&mut self, content: &str, ct: NativeContentType) {
38+
self.before(content, ct);
39+
}
40+
#[inline]
41+
fn native_after(&mut self, content: &str, ct: NativeContentType) {
42+
self.after(content, ct);
43+
}
44+
}
45+
2446
#[pymethods]
2547
impl Element {
2648
#[getter]
@@ -99,53 +121,37 @@ impl Element {
99121
}
100122

101123
#[pyo3(signature = (content, content_type=None))]
102-
103-
pub fn prepend(
104-
&mut self,
105-
content: &str,
106-
content_type: Option<ContentType>,
107-
) -> PyResult<()> {
124+
pub fn prepend(&mut self, content: &str, content_type: Option<ContentType>) -> PyResult<()> {
108125
self.inner
109126
.get_mut()?
110127
.prepend(content, content_type.into_native());
111128
Ok(())
112129
}
113130

114131
#[pyo3(signature = (content, content_type=None))]
115-
pub fn append(
116-
&mut self,
117-
content: &str,
118-
content_type: Option<ContentType>,
119-
) -> PyResult<()> {
132+
pub fn append(&mut self, content: &str, content_type: Option<ContentType>) -> PyResult<()> {
120133
self.inner
121134
.get_mut()?
122135
.append(content, content_type.into_native());
123136
Ok(())
124137
}
125138

126-
127139
#[pyo3(signature = (content, content_type=None))]
128-
pub fn before(
129-
&mut self,
130-
content: &str,
131-
content_type: Option<ContentType>,
132-
) -> PyResult<()> {
133-
self.inner
134-
.get_mut()?
135-
.before(content, content_type.into_native());
136-
Ok(())
140+
pub fn before(&mut self, content: &str, content_type: Option<ContentType>) -> PyResult<()> {
141+
<Self as PyBeforeAfter<NativeElement<'static, 'static>>>::before_impl(
142+
self,
143+
content,
144+
content_type,
145+
)
137146
}
138147

139148
#[pyo3(signature = (content, content_type=None))]
140-
pub fn after(
141-
&mut self,
142-
content: &str,
143-
content_type: Option<ContentType>,
144-
) -> PyResult<()> {
145-
self.inner
146-
.get_mut()?
147-
.after(content, content_type.into_native());
148-
Ok(())
149+
pub fn after(&mut self, content: &str, content_type: Option<ContentType>) -> PyResult<()> {
150+
<Self as PyBeforeAfter<NativeElement<'static, 'static>>>::after_impl(
151+
self,
152+
content,
153+
content_type,
154+
)
149155
}
150156

151157
#[pyo3(signature = (content, content_type=None))]

src/end_tag.rs

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
use lol_html::html_content::ContentType as NativeContentType;
12
use lol_html::html_content::EndTag as NativeEndTag;
23
use pyo3::exceptions::PyRuntimeError;
34
use pyo3::prelude::*;
45

5-
use crate::{ContentType, HasNative, IntoNative, NativeRefWrap};
6+
use crate::{ContentType, HasInner, HasNative, NativeBeforeAfter, NativeRefWrap, PyBeforeAfter};
67

78
#[pyclass(unsendable)]
89
pub struct EndTag {
@@ -13,6 +14,24 @@ impl HasNative for EndTag {
1314
type Native = NativeEndTag<'static>;
1415
}
1516

17+
impl HasInner<NativeEndTag<'static>> for EndTag {
18+
#[inline]
19+
fn inner_native(&mut self) -> &mut NativeRefWrap<NativeEndTag<'static>> {
20+
&mut self.inner
21+
}
22+
}
23+
24+
impl NativeBeforeAfter for lol_html::html_content::EndTag<'static> {
25+
#[inline]
26+
fn native_before(&mut self, content: &str, ct: NativeContentType) {
27+
self.before(content, ct);
28+
}
29+
#[inline]
30+
fn native_after(&mut self, content: &str, ct: NativeContentType) {
31+
self.after(content, ct);
32+
}
33+
}
34+
1635
#[pymethods]
1736
impl EndTag {
1837
#[getter]
@@ -30,27 +49,13 @@ impl EndTag {
3049
}
3150

3251
#[pyo3(signature = (content, content_type=None))]
33-
pub fn before(
34-
&mut self,
35-
content: &str,
36-
content_type: Option<ContentType>,
37-
) -> PyResult<()> {
38-
self.inner
39-
.get_mut()?
40-
.before(content, content_type.into_native());
41-
Ok(())
52+
pub fn before(&mut self, content: &str, content_type: Option<ContentType>) -> PyResult<()> {
53+
<Self as PyBeforeAfter<NativeEndTag<'static>>>::before_impl(self, content, content_type)
4254
}
4355

4456
#[pyo3(signature = (content, content_type=None))]
45-
pub fn after(
46-
&mut self,
47-
content: &str,
48-
content_type: Option<ContentType>,
49-
) -> PyResult<()> {
50-
self.inner
51-
.get_mut()?
52-
.after(content, content_type.into_native());
53-
Ok(())
57+
pub fn after(&mut self, content: &str, content_type: Option<ContentType>) -> PyResult<()> {
58+
<Self as PyBeforeAfter<NativeEndTag<'static>>>::after_impl(self, content, content_type)
5459
}
5560

5661
pub fn remove(&mut self) -> PyResult<()> {

src/html_rewriter.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ impl OutputSink for PythonOutputSink {
5656
}
5757
}
5858

59-
6059
fn rewriting_error_to_py(err: RewritingError) -> PyErr {
6160
match err {
6261
RewritingError::ContentHandlerError(e) => {

src/lib.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,41 @@ impl IntoNative<NativeContentType> for Option<ContentType> {
125125
}
126126
}
127127

128+
pub trait HasInner<N> {
129+
fn inner_native(&mut self) -> &mut NativeRefWrap<N>;
130+
}
131+
132+
pub trait NativeBeforeAfter {
133+
fn native_before(&mut self, content: &str, ct: NativeContentType);
134+
fn native_after(&mut self, content: &str, ct: NativeContentType);
135+
}
136+
137+
pub trait PyBeforeAfter<N>: HasInner<N>
138+
where
139+
N: NativeBeforeAfter,
140+
{
141+
#[inline]
142+
fn before_impl(&mut self, content: &str, content_type: Option<ContentType>) -> PyResult<()> {
143+
let ct = content_type.into_native();
144+
self.inner_native().get_mut()?.native_before(content, ct);
145+
Ok(())
146+
}
147+
148+
#[inline]
149+
fn after_impl(&mut self, content: &str, content_type: Option<ContentType>) -> PyResult<()> {
150+
let ct = content_type.into_native();
151+
self.inner_native().get_mut()?.native_after(content, ct);
152+
Ok(())
153+
}
154+
}
155+
156+
impl<T, N> PyBeforeAfter<N> for T
157+
where
158+
T: HasInner<N>,
159+
N: NativeBeforeAfter,
160+
{
161+
}
162+
128163
use comment::Comment as PyComment;
129164
use doctype::Doctype as PyDoctype;
130165
use document_end::DocumentEnd as PyDocumentEnd;

0 commit comments

Comments
 (0)