Files
hakorune/src/boxes/regex/mod.rs

142 lines
3.8 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! RegexBox 🔍 - 正規表現
// Nyashの箱システムによる正規表現処理を提供します。
// 参考: 既存Boxの設計思想
use crate::box_trait::{BoolBox, BoxBase, BoxCore, NyashBox, StringBox};
use crate::boxes::array::ArrayBox;
use regex::Regex;
use std::any::Any;
use std::fmt::Debug;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct RegexBox {
regex: Arc<Regex>,
pattern: Arc<String>,
base: BoxBase,
}
impl RegexBox {
pub fn new(pattern: &str) -> Result<Self, regex::Error> {
let regex = Regex::new(pattern)?;
Ok(RegexBox {
regex: Arc::new(regex),
pattern: Arc::new(pattern.to_string()),
base: BoxBase::new(),
})
}
pub fn is_match(&self, text: &str) -> bool {
self.regex.is_match(text)
}
pub fn pattern(&self) -> &str {
&self.pattern
}
/// パターンマッチテスト
pub fn test(&self, text: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
let text_str = text.to_string_box().value;
Box::new(BoolBox::new(self.is_match(&text_str)))
}
/// マッチ箇所を検索
pub fn find(&self, text: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
let text_str = text.to_string_box().value;
if let Some(mat) = self.regex.find(&text_str) {
Box::new(StringBox::new(mat.as_str()))
} else {
Box::new(crate::boxes::null_box::NullBox::new())
}
}
/// すべてのマッチを検索
pub fn find_all(&self, text: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
let text_str = text.to_string_box().value;
let array = ArrayBox::new();
for mat in self.regex.find_iter(&text_str) {
let _ = array.push(Box::new(StringBox::new(mat.as_str())));
}
Box::new(array)
}
/// 文字列置換
pub fn replace(
&self,
text: Box<dyn NyashBox>,
replacement: Box<dyn NyashBox>,
) -> Box<dyn NyashBox> {
let text_str = text.to_string_box().value;
let replacement_str = replacement.to_string_box().value;
let result = self.regex.replace_all(&text_str, replacement_str.as_str());
Box::new(StringBox::new(&result.to_string()))
}
/// 文字列分割
pub fn split(&self, text: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
let text_str = text.to_string_box().value;
let array = ArrayBox::new();
for part in self.regex.split(&text_str) {
let _ = array.push(Box::new(StringBox::new(part)));
}
Box::new(array)
}
}
impl NyashBox for RegexBox {
fn clone_box(&self) -> Box<dyn NyashBox> {
Box::new(self.clone())
}
/// 仮実装: clone_boxと同じ後で修正
fn share_box(&self) -> Box<dyn NyashBox> {
self.clone_box()
}
fn to_string_box(&self) -> StringBox {
StringBox::new(format!("RegexBox({})", self.pattern.as_str()))
}
fn type_name(&self) -> &'static str {
"RegexBox"
}
fn equals(&self, other: &dyn NyashBox) -> BoolBox {
if let Some(other_regex) = other.as_any().downcast_ref::<RegexBox>() {
BoolBox::new(self.pattern.as_str() == other_regex.pattern.as_str())
} else {
BoolBox::new(false)
}
}
}
impl BoxCore for RegexBox {
fn box_id(&self) -> u64 {
self.base.id
}
fn parent_type_id(&self) -> Option<std::any::TypeId> {
self.base.parent_type_id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "RegexBox({})", self.pattern.as_str())
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
impl std::fmt::Display for RegexBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.fmt_box(f)
}
}