use std::ops::Range;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PtSplit {
pub range: Range<usize>,
pub token_id: Option<u32>,
}
impl PtSplit {
#[inline]
pub fn from_range(range: Range<usize>) -> Self {
Self {
range,
token_id: None,
}
}
#[inline]
pub fn from_token(span: usize, token: u32) -> Self {
Self {
range: span..span,
token_id: Some(token),
}
}
}
#[derive(Debug, Clone)]
pub struct PreTokenizedString {
pub buffer: String,
pub splits: Vec<PtSplit>,
}
impl PreTokenizedString {
pub const EMPTY: Self = Self {
buffer: String::new(),
splits: Vec::new(),
};
pub fn new(buffer: String, splits: Vec<PtSplit>) -> Self {
Self { buffer, splits }
}
pub fn split_text(&self, split: &PtSplit) -> &str {
&self.buffer[split.range.clone()]
}
pub fn texts(&self) -> impl Iterator<Item = &str> + '_ {
self.splits.iter().filter_map(|s| {
if s.token_id.is_some() {
return None;
}
let text = &self.buffer[s.range.clone()];
if text.is_empty() { None } else { Some(text) }
})
}
pub fn added_token_count(&self) -> usize {
self.splits.iter().filter(|s| s.token_id.is_some()).count()
}
}