-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtext_wrapper.rs
More file actions
127 lines (106 loc) · 3.48 KB
/
text_wrapper.rs
File metadata and controls
127 lines (106 loc) · 3.48 KB
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use super::hybrid_wrapper::HybridWrapper;
use super::types::*;
use unicode_width::UnicodeWidthStr;
pub struct TextWrapper {
config: WrapConfig,
wrapper: Box<dyn WordWrapper>,
}
impl TextWrapper {
pub fn new(config: WrapConfig) -> Self {
let wrapper: Box<dyn WordWrapper> = match config.strategy {
WrapStrategy::WordBoundary => Box::new(WordBoundaryWrapper::new()),
WrapStrategy::Hybrid => Box::new(HybridWrapper::new()),
WrapStrategy::Semantic => Box::new(SemanticWrapper::new()),
};
Self { config, wrapper }
}
pub fn wrap(&self, text: &str) -> String {
self.wrapper.wrap_text(text, &self.config)
}
}
impl Default for TextWrapper {
fn default() -> Self {
Self::new(WrapConfig::default())
}
}
// 单词边界包装器
pub struct WordBoundaryWrapper {
inner: HybridWrapper,
}
impl WordBoundaryWrapper {
pub fn new() -> Self {
Self {
inner: HybridWrapper::new(),
}
}
}
impl WordWrapper for WordBoundaryWrapper {
fn wrap_text(&self, text: &str, config: &WrapConfig) -> String {
let mut word_config = config.clone();
word_config.strategy = WrapStrategy::WordBoundary;
self.inner.wrap_text(text, &word_config)
}
fn wrap_segments(&self, segments: &[TextSegment], config: &WrapConfig) -> String {
let mut word_config = config.clone();
word_config.strategy = WrapStrategy::WordBoundary;
self.inner.wrap_segments(segments, &word_config)
}
}
// 字符包装器
#[allow(dead_code)]
pub struct CharacterWrapper;
impl WordWrapper for CharacterWrapper {
fn wrap_text(&self, text: &str, config: &WrapConfig) -> String {
let max_width = config.max_width;
let indent = &config.indent;
let hanging = &config.hanging_indent;
let mut lines = Vec::new();
let mut current_line = indent.clone();
for ch in text.chars() {
if current_line.width() >= max_width && !current_line.trim().is_empty() {
lines.push(current_line);
current_line = hanging.clone();
}
current_line.push(ch);
}
if !current_line.is_empty() {
lines.push(current_line);
}
lines.join("\n")
}
fn wrap_segments(&self, segments: &[TextSegment], config: &WrapConfig) -> String {
let text: String = segments
.iter()
.map(|seg| match seg {
TextSegment::PlainText(s) => s.clone(),
TextSegment::CodeBlock(s) => s.clone(),
TextSegment::Link(_, text) => text.clone(),
TextSegment::InlineCode(s) => s.clone(),
})
.collect();
self.wrap_text(&text, config)
}
}
// 语义包装器
pub struct SemanticWrapper {
inner: HybridWrapper,
}
impl SemanticWrapper {
pub fn new() -> Self {
Self {
inner: HybridWrapper::new(),
}
}
}
impl WordWrapper for SemanticWrapper {
fn wrap_text(&self, text: &str, config: &WrapConfig) -> String {
let mut semantic_config = config.clone();
semantic_config.strategy = WrapStrategy::Semantic;
self.inner.wrap_text(text, &semantic_config)
}
fn wrap_segments(&self, segments: &[TextSegment], config: &WrapConfig) -> String {
let mut semantic_config = config.clone();
semantic_config.strategy = WrapStrategy::Semantic;
self.inner.wrap_segments(segments, &semantic_config)
}
}