Skip to content

Commit 762cb7d

Browse files
authored
♻️ refactor: rustify xml_to_ass and protobuf_to_ass (#336)
1 parent c53b8e0 commit 762cb7d

File tree

11 files changed

+270
-149
lines changed

11 files changed

+270
-149
lines changed

justfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ docker-publish:
9595
build-biliass:
9696
cd packages/biliass; maturin build
9797

98-
develop-biliass:
99-
cd packages/biliass; maturin develop --uv
98+
develop-biliass *ARGS:
99+
cd packages/biliass; maturin develop --uv {{ARGS}}
100100

101101
release-biliass:
102102
@echo 'Tagging biliass@{{BILIASS_VERSION}}...'

packages/biliass/rust/src/comment.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#[derive(Debug, PartialEq, Clone)]
1+
#[derive(Debug, PartialEq, Clone, PartialOrd)]
22
pub enum CommentPosition {
33
/// Regular moving comment
44
Scroll,
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
use crate::comment::{Comment, CommentPosition};
2+
use crate::error::BiliassError;
3+
use crate::writer;
4+
use crate::writer::rows;
5+
use regex::Regex;
6+
7+
#[allow(clippy::too_many_arguments)]
8+
pub fn process_comments(
9+
comments: &Vec<Comment>,
10+
width: u32,
11+
height: u32,
12+
bottom_reserved: u32,
13+
fontface: &str,
14+
fontsize: f32,
15+
alpha: f32,
16+
duration_marquee: f64,
17+
duration_still: f64,
18+
filters_regex: Vec<String>,
19+
reduced: bool,
20+
) -> Result<String, BiliassError> {
21+
let styleid = "biliass";
22+
let mut ass_result = "".to_owned();
23+
ass_result += &writer::ass::write_head(width, height, fontface, fontsize, alpha, styleid);
24+
let mut rows = rows::init_rows(4, (height - bottom_reserved + 1) as usize);
25+
let compiled_regexes_res: Result<Vec<Regex>, regex::Error> = filters_regex
26+
.into_iter()
27+
.map(|pattern| Regex::new(&pattern))
28+
.collect();
29+
let compiled_regexes = compiled_regexes_res.map_err(BiliassError::from)?;
30+
for comment in comments {
31+
match comment.pos {
32+
CommentPosition::Scroll
33+
| CommentPosition::Bottom
34+
| CommentPosition::Top
35+
| CommentPosition::Reversed => {
36+
if compiled_regexes
37+
.iter()
38+
.any(|regex| regex.is_match(&comment.comment))
39+
{
40+
continue;
41+
};
42+
ass_result += &writer::ass::write_normal_comment(
43+
rows.as_mut(),
44+
comment,
45+
width,
46+
height,
47+
bottom_reserved,
48+
fontsize,
49+
duration_marquee,
50+
duration_still,
51+
styleid,
52+
reduced,
53+
);
54+
}
55+
CommentPosition::Special => {
56+
ass_result += &writer::ass::write_special_comment(comment, width, height, styleid);
57+
}
58+
}
59+
}
60+
Ok(ass_result)
61+
}
62+
63+
#[allow(clippy::too_many_arguments)]
64+
pub fn convert_to_ass<Reader, Input>(
65+
inputs: Vec<Input>,
66+
reader: Reader,
67+
stage_width: u32,
68+
stage_height: u32,
69+
reserve_blank: u32,
70+
font_face: &str,
71+
font_size: f32,
72+
text_opacity: f32,
73+
duration_marquee: f64,
74+
duration_still: f64,
75+
comment_filters: Vec<String>,
76+
is_reduce_comments: bool,
77+
) -> Result<String, BiliassError>
78+
where
79+
Reader: Fn(Input, f32) -> Result<Vec<Comment>, BiliassError>,
80+
{
81+
let comments_result: Result<Vec<Vec<Comment>>, BiliassError> = inputs
82+
.into_iter()
83+
.map(|input| reader(input, font_size))
84+
.collect();
85+
let comments = comments_result?;
86+
let mut comments = comments.concat();
87+
comments.sort_by(|a, b| {
88+
(
89+
a.timeline,
90+
a.timestamp,
91+
a.no,
92+
&a.comment,
93+
&a.pos,
94+
a.color,
95+
a.size,
96+
a.height,
97+
a.width,
98+
)
99+
.partial_cmp(&(
100+
b.timeline,
101+
b.timestamp,
102+
b.no,
103+
&b.comment,
104+
&b.pos,
105+
b.color,
106+
a.size,
107+
a.height,
108+
a.width,
109+
))
110+
.unwrap_or(std::cmp::Ordering::Less)
111+
});
112+
process_comments(
113+
&comments,
114+
stage_width,
115+
stage_height,
116+
reserve_blank,
117+
font_face,
118+
font_size,
119+
text_opacity,
120+
duration_marquee,
121+
duration_still,
122+
comment_filters,
123+
is_reduce_comments,
124+
)
125+
}

packages/biliass/rust/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod comment;
2+
mod convert;
23
mod error;
34
mod proto;
45
mod python;
@@ -34,6 +35,7 @@ fn biliass_pyo3(m: &Bound<'_, PyModule>) -> PyResult<()> {
3435
m
3536
)?)?;
3637
m.add_function(wrap_pyfunction!(python::py_write_special_comment, m)?)?;
37-
m.add_function(wrap_pyfunction!(python::py_process_comments, m)?)?;
38+
m.add_function(wrap_pyfunction!(python::py_xml_to_ass, m)?)?;
39+
m.add_function(wrap_pyfunction!(python::py_protobuf_to_ass, m)?)?;
3840
Ok(())
3941
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use crate::{convert, reader};
2+
use pyo3::{
3+
prelude::*,
4+
pybacked::{PyBackedBytes, PyBackedStr},
5+
};
6+
7+
#[allow(clippy::too_many_arguments)]
8+
#[pyfunction(name = "xml_to_ass")]
9+
pub fn py_xml_to_ass(
10+
inputs: Vec<PyBackedStr>,
11+
stage_width: u32,
12+
stage_height: u32,
13+
reserve_blank: u32,
14+
font_face: &str,
15+
font_size: f32,
16+
text_opacity: f32,
17+
duration_marquee: f64,
18+
duration_still: f64,
19+
comment_filters: Vec<String>,
20+
is_reduce_comments: bool,
21+
) -> PyResult<String> {
22+
Ok(convert::convert_to_ass(
23+
inputs,
24+
crate::reader::xml::read_comments_from_xml,
25+
stage_width,
26+
stage_height,
27+
reserve_blank,
28+
font_face,
29+
font_size,
30+
text_opacity,
31+
duration_marquee,
32+
duration_still,
33+
comment_filters,
34+
is_reduce_comments,
35+
)?)
36+
}
37+
38+
#[allow(clippy::too_many_arguments)]
39+
#[pyfunction(name = "protobuf_to_ass")]
40+
pub fn py_protobuf_to_ass(
41+
// inputs: Vec<Py<PyAny>>,
42+
inputs: Vec<PyBackedBytes>,
43+
stage_width: u32,
44+
stage_height: u32,
45+
reserve_blank: u32,
46+
font_face: &str,
47+
font_size: f32,
48+
text_opacity: f32,
49+
duration_marquee: f64,
50+
duration_still: f64,
51+
comment_filters: Vec<String>,
52+
is_reduce_comments: bool,
53+
) -> PyResult<String> {
54+
Ok(convert::convert_to_ass(
55+
inputs,
56+
reader::protobuf::read_comments_from_protobuf,
57+
stage_width,
58+
stage_height,
59+
reserve_blank,
60+
font_face,
61+
font_size,
62+
text_opacity,
63+
duration_marquee,
64+
duration_still,
65+
comment_filters,
66+
is_reduce_comments,
67+
)?)
68+
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
mod comment;
2+
mod convert;
23
mod proto;
34
mod reader;
45
mod writer;
56

67
pub use comment::{PyComment, PyCommentPosition};
8+
pub use convert::{py_protobuf_to_ass, py_xml_to_ass};
79
pub use proto::{PyDanmakuElem, PyDmSegMobileReply};
810
pub use reader::{
911
py_parse_special_comment, py_read_comments_from_protobuf, py_read_comments_from_xml,
1012
};
1113
pub use writer::{
12-
py_process_comments, py_write_comment_with_animation, py_write_head, py_write_normal_comment,
14+
py_write_comment_with_animation, py_write_head, py_write_normal_comment,
1315
py_write_special_comment, PyRows,
1416
};

packages/biliass/rust/src/python/writer.rs

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
use crate::comment::CommentPosition;
2-
use crate::error::BiliassError;
31
use crate::python;
42
use crate::writer::{self, rows};
5-
use regex::Regex;
63

74
use pyo3::prelude::*;
85

@@ -123,61 +120,3 @@ pub fn py_write_special_comment(
123120
styleid,
124121
))
125122
}
126-
127-
#[allow(clippy::too_many_arguments)]
128-
#[pyfunction(name = "process_comments")]
129-
pub fn py_process_comments(
130-
comments: Vec<PyRef<crate::python::PyComment>>,
131-
width: u32,
132-
height: u32,
133-
bottom_reserved: u32,
134-
fontface: &str,
135-
fontsize: f32,
136-
alpha: f32,
137-
duration_marquee: f64,
138-
duration_still: f64,
139-
filters_regex: Vec<String>,
140-
reduced: bool,
141-
) -> PyResult<String> {
142-
let styleid = "biliass";
143-
let mut ass_result = "".to_owned();
144-
ass_result += &writer::ass::write_head(width, height, fontface, fontsize, alpha, styleid);
145-
let mut rows = rows::init_rows(4, (height - bottom_reserved + 1) as usize);
146-
let compiled_regexes_res: Result<Vec<Regex>, regex::Error> = filters_regex
147-
.into_iter()
148-
.map(|pattern| Regex::new(&pattern))
149-
.collect();
150-
let compiled_regexes = compiled_regexes_res.map_err(BiliassError::from)?;
151-
for comment in comments.into_iter() {
152-
match comment.inner.pos {
153-
CommentPosition::Scroll
154-
| CommentPosition::Bottom
155-
| CommentPosition::Top
156-
| CommentPosition::Reversed => {
157-
if compiled_regexes
158-
.iter()
159-
.any(|regex| regex.is_match(&comment.inner.comment))
160-
{
161-
continue;
162-
};
163-
ass_result += &writer::ass::write_normal_comment(
164-
rows.as_mut(),
165-
&comment.inner,
166-
width,
167-
height,
168-
bottom_reserved,
169-
fontsize,
170-
duration_marquee,
171-
duration_still,
172-
styleid,
173-
reduced,
174-
);
175-
}
176-
CommentPosition::Special => {
177-
ass_result +=
178-
&writer::ass::write_special_comment(&comment.inner, width, height, styleid);
179-
}
180-
}
181-
}
182-
Ok(ass_result)
183-
}

packages/biliass/rust/src/reader/protobuf.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ use crate::reader::utils;
55
use prost::Message;
66
use std::io::Cursor;
77

8-
pub fn read_comments_from_protobuf(
9-
data: &[u8],
10-
fontsize: f32,
11-
) -> Result<Vec<Comment>, BiliassError> {
8+
pub fn read_comments_from_protobuf<T>(data: T, fontsize: f32) -> Result<Vec<Comment>, BiliassError>
9+
where
10+
T: AsRef<[u8]>,
11+
{
1212
let replies = DmSegMobileReply::decode(&mut Cursor::new(data))
1313
.map_err(DecodeError::from)
1414
.map_err(BiliassError::from)?;

packages/biliass/rust/src/reader/xml.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,11 @@ fn parse_comment(
128128
Ok(parsed_p)
129129
}
130130

131-
pub fn read_comments_from_xml(text: &str, fontsize: f32) -> Result<Vec<Comment>, BiliassError> {
132-
let filtered_text = utils::filter_bad_chars(text);
131+
pub fn read_comments_from_xml<T>(text: T, fontsize: f32) -> Result<Vec<Comment>, BiliassError>
132+
where
133+
T: AsRef<str>,
134+
{
135+
let filtered_text = utils::filter_bad_chars(text.as_ref());
133136
let mut reader = Reader::from_str(&filtered_text);
134137

135138
let mut buf = Vec::new();

packages/biliass/src/biliass/_core.pyi

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,29 @@ def parse_special_comment(
100100
content: str, zoom_factor: tuple[float, float, float]
101101
) -> tuple[tuple[int, int, float, float, float, float], int, int, str, int, float, int, str, bool]: ...
102102
def write_special_comment(comment: Comment, width: int, height: int, styleid: str) -> str: ...
103-
def process_comments(
104-
comments: list[Comment],
105-
width: int,
106-
height: int,
107-
bottom_reserved: int,
108-
fontface: str,
109-
fontsize: float,
110-
alpha: float,
103+
def xml_to_ass(
104+
inputs: list[str],
105+
stage_width: int,
106+
stage_height: int,
107+
reserve_blank: int,
108+
font_face: str,
109+
font_size: float,
110+
text_opacity: float,
111111
duration_marquee: float,
112112
duration_still: float,
113-
filters_regex: list[str],
114-
reduced: bool,
113+
comment_filter: list[str],
114+
is_reduce_comments: bool,
115+
) -> str: ...
116+
def protobuf_to_ass(
117+
inputs: list[bytes],
118+
stage_width: int,
119+
stage_height: int,
120+
reserve_blank: int,
121+
font_face: str,
122+
font_size: float,
123+
text_opacity: float,
124+
duration_marquee: float,
125+
duration_still: float,
126+
comment_filter: list[str],
127+
is_reduce_comments: bool,
115128
) -> str: ...

0 commit comments

Comments
 (0)