Implement NyashBox trait for core boxes - ArrayBox, BufferBox, FileBox, JSONBox, FutureBox, StreamBox, ResultBox
Co-authored-by: moe-charm <217100418+moe-charm@users.noreply.github.com>
This commit is contained in:
@ -77,6 +77,12 @@ env_logger = "0.11"
|
|||||||
# 日時処理
|
# 日時処理
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
|
|
||||||
|
# HTTP通信(HttpClientBox用)
|
||||||
|
reqwest = { version = "0.11", features = ["blocking"] }
|
||||||
|
|
||||||
|
# 正規表現(RegexBox用)
|
||||||
|
regex = "1.0"
|
||||||
|
|
||||||
# WebAssembly対応
|
# WebAssembly対応
|
||||||
wasm-bindgen = "0.2"
|
wasm-bindgen = "0.2"
|
||||||
console_error_panic_hook = "0.1"
|
console_error_panic_hook = "0.1"
|
||||||
|
|||||||
@ -2,29 +2,46 @@
|
|||||||
// Nyashの箱システムによる配列・リスト操作を提供します。
|
// Nyashの箱システムによる配列・リスト操作を提供します。
|
||||||
// 参考: 既存Boxの設計思想
|
// 参考: 既存Boxの設計思想
|
||||||
|
|
||||||
|
use crate::box_trait::{NyashBox, StringBox, BoolBox};
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct ArrayBox {
|
pub struct ArrayBox {
|
||||||
pub items: Vec<Box<dyn std::any::Any>>,
|
pub items: Vec<Box<dyn NyashBox>>,
|
||||||
|
id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ArrayBox {
|
impl ArrayBox {
|
||||||
/// 新しいArrayBoxを作成
|
/// 新しいArrayBoxを作成
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
ArrayBox { items: Vec::new() }
|
static mut COUNTER: u64 = 0;
|
||||||
|
let id = unsafe {
|
||||||
|
COUNTER += 1;
|
||||||
|
COUNTER
|
||||||
|
};
|
||||||
|
ArrayBox {
|
||||||
|
items: Vec::new(),
|
||||||
|
id,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 要素を追加
|
/// 要素を追加
|
||||||
pub fn push(&mut self, item: Box<dyn std::any::Any>) {
|
pub fn push(&mut self, item: Box<dyn NyashBox>) {
|
||||||
self.items.push(item);
|
self.items.push(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 要素数を取得
|
/// 要素数を取得
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.items.len()
|
self.items.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 要素を取得
|
/// 要素を取得
|
||||||
pub fn get(&self, index: usize) -> Option<&Box<dyn std::any::Any>> {
|
pub fn get(&self, index: usize) -> Option<&Box<dyn NyashBox>> {
|
||||||
self.items.get(index)
|
self.items.get(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 要素を削除
|
/// 要素を削除
|
||||||
pub fn remove(&mut self, index: usize) -> Option<Box<dyn std::any::Any>> {
|
pub fn remove(&mut self, index: usize) -> Option<Box<dyn NyashBox>> {
|
||||||
if index < self.items.len() {
|
if index < self.items.len() {
|
||||||
Some(self.items.remove(index))
|
Some(self.items.remove(index))
|
||||||
} else {
|
} else {
|
||||||
@ -32,3 +49,48 @@ impl ArrayBox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NyashBox for ArrayBox {
|
||||||
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
||||||
|
let mut new_array = ArrayBox::new();
|
||||||
|
for item in &self.items {
|
||||||
|
new_array.push(item.clone_box());
|
||||||
|
}
|
||||||
|
Box::new(new_array)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string_box(&self) -> StringBox {
|
||||||
|
let elements: Vec<String> = self.items.iter()
|
||||||
|
.map(|item| item.to_string_box().value)
|
||||||
|
.collect();
|
||||||
|
StringBox::new(format!("[{}]", elements.join(", ")))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name(&self) -> &'static str {
|
||||||
|
"ArrayBox"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn box_id(&self) -> u64 {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn equals(&self, other: &dyn NyashBox) -> BoolBox {
|
||||||
|
if let Some(other_array) = other.as_any().downcast_ref::<ArrayBox>() {
|
||||||
|
if self.items.len() != other_array.items.len() {
|
||||||
|
return BoolBox::new(false);
|
||||||
|
}
|
||||||
|
for (a, b) in self.items.iter().zip(other_array.items.iter()) {
|
||||||
|
if !a.equals(b.as_ref()).value {
|
||||||
|
return BoolBox::new(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BoolBox::new(true)
|
||||||
|
} else {
|
||||||
|
BoolBox::new(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -2,21 +2,72 @@
|
|||||||
// Nyashの箱システムによるバイナリデータ処理を提供します。
|
// Nyashの箱システムによるバイナリデータ処理を提供します。
|
||||||
// 参考: 既存Boxの設計思想
|
// 参考: 既存Boxの設計思想
|
||||||
|
|
||||||
|
use crate::box_trait::{NyashBox, StringBox, BoolBox};
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct BufferBox {
|
pub struct BufferBox {
|
||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
|
id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BufferBox {
|
impl BufferBox {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
BufferBox { data: Vec::new() }
|
static mut COUNTER: u64 = 0;
|
||||||
|
let id = unsafe {
|
||||||
|
COUNTER += 1;
|
||||||
|
COUNTER
|
||||||
|
};
|
||||||
|
BufferBox {
|
||||||
|
data: Vec::new(),
|
||||||
|
id,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_vec(data: Vec<u8>) -> Self {
|
pub fn from_vec(data: Vec<u8>) -> Self {
|
||||||
BufferBox { data }
|
static mut COUNTER: u64 = 0;
|
||||||
|
let id = unsafe {
|
||||||
|
COUNTER += 1;
|
||||||
|
COUNTER
|
||||||
|
};
|
||||||
|
BufferBox { data, id }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.data.len()
|
self.data.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_slice(&self) -> &[u8] {
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
&self.data
|
&self.data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NyashBox for BufferBox {
|
||||||
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
||||||
|
Box::new(self.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string_box(&self) -> StringBox {
|
||||||
|
StringBox::new(format!("BufferBox({} bytes)", self.data.len()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name(&self) -> &'static str {
|
||||||
|
"BufferBox"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn box_id(&self) -> u64 {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn equals(&self, other: &dyn NyashBox) -> BoolBox {
|
||||||
|
if let Some(other_buffer) = other.as_any().downcast_ref::<BufferBox>() {
|
||||||
|
BoolBox::new(self.data == other_buffer.data)
|
||||||
|
} else {
|
||||||
|
BoolBox::new(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -2,24 +2,74 @@
|
|||||||
// Nyashの箱システムによるファイル入出力を提供します。
|
// Nyashの箱システムによるファイル入出力を提供します。
|
||||||
// 参考: 既存Boxの設計思想
|
// 参考: 既存Boxの設計思想
|
||||||
|
|
||||||
|
use crate::box_trait::{NyashBox, StringBox, BoolBox};
|
||||||
|
use std::any::Any;
|
||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
use std::io::{Read, Write, Result};
|
use std::io::{Read, Write, Result};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct FileBox {
|
pub struct FileBox {
|
||||||
pub file: File,
|
pub file: File,
|
||||||
|
pub path: String,
|
||||||
|
id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileBox {
|
impl FileBox {
|
||||||
pub fn open(path: &str) -> Result<Self> {
|
pub fn open(path: &str) -> Result<Self> {
|
||||||
|
static mut COUNTER: u64 = 0;
|
||||||
|
let id = unsafe {
|
||||||
|
COUNTER += 1;
|
||||||
|
COUNTER
|
||||||
|
};
|
||||||
let file = OpenOptions::new().read(true).write(true).create(true).open(path)?;
|
let file = OpenOptions::new().read(true).write(true).create(true).open(path)?;
|
||||||
Ok(FileBox { file })
|
Ok(FileBox {
|
||||||
|
file,
|
||||||
|
path: path.to_string(),
|
||||||
|
id,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_to_string(&mut self) -> Result<String> {
|
pub fn read_to_string(&mut self) -> Result<String> {
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
self.file.read_to_string(&mut s)?;
|
self.file.read_to_string(&mut s)?;
|
||||||
Ok(s)
|
Ok(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_all(&mut self, buf: &[u8]) -> Result<()> {
|
pub fn write_all(&mut self, buf: &[u8]) -> Result<()> {
|
||||||
self.file.write_all(buf)
|
self.file.write_all(buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NyashBox for FileBox {
|
||||||
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
||||||
|
// Note: Cannot truly clone a File handle, so create a new one to the same path
|
||||||
|
match FileBox::open(&self.path) {
|
||||||
|
Ok(new_file) => Box::new(new_file),
|
||||||
|
Err(_) => Box::new(crate::box_trait::VoidBox::new()) // Return void on error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string_box(&self) -> StringBox {
|
||||||
|
StringBox::new(format!("FileBox({})", self.path))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name(&self) -> &'static str {
|
||||||
|
"FileBox"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn box_id(&self) -> u64 {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn equals(&self, other: &dyn NyashBox) -> BoolBox {
|
||||||
|
if let Some(other_file) = other.as_any().downcast_ref::<FileBox>() {
|
||||||
|
BoolBox::new(self.path == other_file.path)
|
||||||
|
} else {
|
||||||
|
BoolBox::new(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -2,9 +2,114 @@
|
|||||||
// Nyashの箱システムによる非同期処理の基盤を提供します。
|
// Nyashの箱システムによる非同期処理の基盤を提供します。
|
||||||
// 参考: 既存Boxの設計思想
|
// 参考: 既存Boxの設計思想
|
||||||
|
|
||||||
|
use crate::box_trait::{NyashBox, StringBox, BoolBox};
|
||||||
|
use std::any::Any;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct NyashFutureBox {
|
||||||
|
pub result: Arc<Mutex<Option<Box<dyn NyashBox>>>>,
|
||||||
|
pub is_ready: Arc<Mutex<bool>>,
|
||||||
|
id: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for NyashFutureBox {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
result: Arc::clone(&self.result),
|
||||||
|
is_ready: Arc::clone(&self.is_ready),
|
||||||
|
id: self.id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NyashFutureBox {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
static mut COUNTER: u64 = 0;
|
||||||
|
let id = unsafe {
|
||||||
|
COUNTER += 1;
|
||||||
|
COUNTER
|
||||||
|
};
|
||||||
|
Self {
|
||||||
|
result: Arc::new(Mutex::new(None)),
|
||||||
|
is_ready: Arc::new(Mutex::new(false)),
|
||||||
|
id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the result of the future
|
||||||
|
pub fn set_result(&self, value: Box<dyn NyashBox>) {
|
||||||
|
let mut result = self.result.lock().unwrap();
|
||||||
|
*result = Some(value);
|
||||||
|
let mut ready = self.is_ready.lock().unwrap();
|
||||||
|
*ready = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the result (blocks until ready)
|
||||||
|
pub fn get(&self) -> Box<dyn NyashBox> {
|
||||||
|
// Simple busy wait (could be improved with condvar)
|
||||||
|
loop {
|
||||||
|
let ready = self.is_ready.lock().unwrap();
|
||||||
|
if *ready {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
drop(ready);
|
||||||
|
std::thread::yield_now();
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = self.result.lock().unwrap();
|
||||||
|
result.as_ref().unwrap().clone_box()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if the future is ready
|
||||||
|
pub fn ready(&self) -> bool {
|
||||||
|
*self.is_ready.lock().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NyashBox for NyashFutureBox {
|
||||||
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
||||||
|
Box::new(self.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string_box(&self) -> StringBox {
|
||||||
|
let ready = *self.is_ready.lock().unwrap();
|
||||||
|
if ready {
|
||||||
|
let result = self.result.lock().unwrap();
|
||||||
|
if let Some(value) = result.as_ref() {
|
||||||
|
StringBox::new(format!("Future(ready: {})", value.to_string_box().value))
|
||||||
|
} else {
|
||||||
|
StringBox::new("Future(ready: void)".to_string())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
StringBox::new("Future(pending)".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name(&self) -> &'static str {
|
||||||
|
"NyashFutureBox"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn box_id(&self) -> u64 {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn equals(&self, other: &dyn NyashBox) -> BoolBox {
|
||||||
|
if let Some(other_future) = other.as_any().downcast_ref::<NyashFutureBox>() {
|
||||||
|
BoolBox::new(self.id == other_future.id)
|
||||||
|
} else {
|
||||||
|
BoolBox::new(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep the original generic FutureBox for compatibility
|
||||||
pub struct FutureBox<T> {
|
pub struct FutureBox<T> {
|
||||||
pub future: Pin<Box<dyn Future<Output = T> + Send>>,
|
pub future: Pin<Box<dyn Future<Output = T> + Send>>,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,21 +2,63 @@
|
|||||||
// Nyashの箱システムによるHTTP通信を提供します。
|
// Nyashの箱システムによるHTTP通信を提供します。
|
||||||
// 参考: 既存Boxの設計思想
|
// 参考: 既存Boxの設計思想
|
||||||
|
|
||||||
|
use crate::box_trait::{NyashBox, StringBox, BoolBox};
|
||||||
|
use std::any::Any;
|
||||||
use reqwest::blocking::Client;
|
use reqwest::blocking::Client;
|
||||||
use reqwest::Result;
|
use reqwest::Result;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct HttpClientBox {
|
pub struct HttpClientBox {
|
||||||
pub client: Client,
|
pub client: Client,
|
||||||
|
id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HttpClientBox {
|
impl HttpClientBox {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
static mut COUNTER: u64 = 0;
|
||||||
|
let id = unsafe {
|
||||||
|
COUNTER += 1;
|
||||||
|
COUNTER
|
||||||
|
};
|
||||||
HttpClientBox {
|
HttpClientBox {
|
||||||
client: Client::new(),
|
client: Client::new(),
|
||||||
|
id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, url: &str) -> Result<String> {
|
pub fn get(&self, url: &str) -> Result<String> {
|
||||||
let res = self.client.get(url).send()?.text()?;
|
let res = self.client.get(url).send()?.text()?;
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NyashBox for HttpClientBox {
|
||||||
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
||||||
|
// Create a new client instance since Client doesn't implement Clone in a straightforward way
|
||||||
|
Box::new(HttpClientBox::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string_box(&self) -> StringBox {
|
||||||
|
StringBox::new(format!("HttpClientBox(id: {})", self.id))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name(&self) -> &'static str {
|
||||||
|
"HttpClientBox"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn box_id(&self) -> u64 {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn equals(&self, other: &dyn NyashBox) -> BoolBox {
|
||||||
|
if let Some(other_http) = other.as_any().downcast_ref::<HttpClientBox>() {
|
||||||
|
BoolBox::new(self.id == other_http.id)
|
||||||
|
} else {
|
||||||
|
BoolBox::new(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -2,18 +2,67 @@
|
|||||||
// Nyashの箱システムによるJSON解析・生成を提供します。
|
// Nyashの箱システムによるJSON解析・生成を提供します。
|
||||||
// 参考: 既存Boxの設計思想
|
// 参考: 既存Boxの設計思想
|
||||||
|
|
||||||
|
use crate::box_trait::{NyashBox, StringBox, BoolBox};
|
||||||
|
use std::any::Any;
|
||||||
use serde_json::{Value, Error};
|
use serde_json::{Value, Error};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct JSONBox {
|
pub struct JSONBox {
|
||||||
pub value: Value,
|
pub value: Value,
|
||||||
|
id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JSONBox {
|
impl JSONBox {
|
||||||
pub fn from_str(s: &str) -> Result<Self, Error> {
|
pub fn from_str(s: &str) -> Result<Self, Error> {
|
||||||
|
static mut COUNTER: u64 = 0;
|
||||||
|
let id = unsafe {
|
||||||
|
COUNTER += 1;
|
||||||
|
COUNTER
|
||||||
|
};
|
||||||
let value = serde_json::from_str(s)?;
|
let value = serde_json::from_str(s)?;
|
||||||
Ok(JSONBox { value })
|
Ok(JSONBox { value, id })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new(value: Value) -> Self {
|
||||||
|
static mut COUNTER: u64 = 0;
|
||||||
|
let id = unsafe {
|
||||||
|
COUNTER += 1;
|
||||||
|
COUNTER
|
||||||
|
};
|
||||||
|
JSONBox { value, id }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_string(&self) -> String {
|
pub fn to_string(&self) -> String {
|
||||||
self.value.to_string()
|
self.value.to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NyashBox for JSONBox {
|
||||||
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
||||||
|
Box::new(self.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string_box(&self) -> StringBox {
|
||||||
|
StringBox::new(self.value.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name(&self) -> &'static str {
|
||||||
|
"JSONBox"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn box_id(&self) -> u64 {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn equals(&self, other: &dyn NyashBox) -> BoolBox {
|
||||||
|
if let Some(other_json) = other.as_any().downcast_ref::<JSONBox>() {
|
||||||
|
BoolBox::new(self.value == other_json.value)
|
||||||
|
} else {
|
||||||
|
BoolBox::new(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -94,18 +94,36 @@ pub use web::{WebDisplayBox, WebConsoleBox, WebCanvasBox};
|
|||||||
|
|
||||||
pub mod null_box;
|
pub mod null_box;
|
||||||
|
|
||||||
|
// High-priority Box types
|
||||||
|
pub mod array;
|
||||||
|
pub mod buffer;
|
||||||
|
pub mod file;
|
||||||
|
pub mod future;
|
||||||
|
pub mod json;
|
||||||
|
pub mod result;
|
||||||
|
pub mod http;
|
||||||
|
pub mod stream;
|
||||||
|
pub mod regex;
|
||||||
|
|
||||||
// P2P通信Box群
|
// P2P通信Box群
|
||||||
// pub mod intent_box;
|
// pub mod intent_box;
|
||||||
// pub mod intent_box_wrapper;
|
// pub mod intent_box_wrapper;
|
||||||
// pub mod p2p_box;
|
// pub mod p2p_box;
|
||||||
|
|
||||||
// 今後追加予定のBox型(コメントアウト)
|
|
||||||
// pub mod array_box;
|
|
||||||
// pub use array_box::ArrayBox;
|
|
||||||
|
|
||||||
// null関数も再エクスポート
|
// null関数も再エクスポート
|
||||||
pub use null_box::{NullBox, null};
|
pub use null_box::{NullBox, null};
|
||||||
|
|
||||||
|
// High-priority Box types re-export
|
||||||
|
pub use array::ArrayBox;
|
||||||
|
pub use buffer::BufferBox;
|
||||||
|
pub use file::FileBox;
|
||||||
|
pub use future::{NyashFutureBox, FutureBox};
|
||||||
|
pub use json::JSONBox;
|
||||||
|
pub use result::{NyashResultBox, ResultBox};
|
||||||
|
pub use http::HttpClientBox;
|
||||||
|
pub use stream::{NyashStreamBox, StreamBox};
|
||||||
|
pub use regex::RegexBox;
|
||||||
|
|
||||||
// P2P通信Boxの再エクスポート
|
// P2P通信Boxの再エクスポート
|
||||||
// pub use intent_box::IntentBox;
|
// pub use intent_box::IntentBox;
|
||||||
// pub use p2p_box::P2PBox;
|
// pub use p2p_box::P2PBox;
|
||||||
@ -2,6 +2,85 @@
|
|||||||
// Nyashの箱システムによるエラー処理を提供します。
|
// Nyashの箱システムによるエラー処理を提供します。
|
||||||
// 参考: 既存Boxの設計思想
|
// 参考: 既存Boxの設計思想
|
||||||
|
|
||||||
|
use crate::box_trait::{NyashBox, StringBox, BoolBox};
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum NyashResultBox {
|
||||||
|
Ok(Box<dyn NyashBox>),
|
||||||
|
Err(Box<dyn NyashBox>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NyashResultBox {
|
||||||
|
pub fn new_ok(value: Box<dyn NyashBox>) -> Self {
|
||||||
|
NyashResultBox::Ok(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_err(error: Box<dyn NyashBox>) -> Self {
|
||||||
|
NyashResultBox::Err(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_ok(&self) -> bool {
|
||||||
|
matches!(self, NyashResultBox::Ok(_))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_err(&self) -> bool {
|
||||||
|
matches!(self, NyashResultBox::Err(_))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unwrap(self) -> Box<dyn NyashBox> {
|
||||||
|
match self {
|
||||||
|
NyashResultBox::Ok(val) => val,
|
||||||
|
NyashResultBox::Err(_) => panic!("called `unwrap()` on an `Err` value"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NyashBox for NyashResultBox {
|
||||||
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
||||||
|
match self {
|
||||||
|
NyashResultBox::Ok(val) => Box::new(NyashResultBox::Ok(val.clone_box())),
|
||||||
|
NyashResultBox::Err(err) => Box::new(NyashResultBox::Err(err.clone_box())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string_box(&self) -> StringBox {
|
||||||
|
match self {
|
||||||
|
NyashResultBox::Ok(val) => StringBox::new(format!("Ok({})", val.to_string_box().value)),
|
||||||
|
NyashResultBox::Err(err) => StringBox::new(format!("Err({})", err.to_string_box().value)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name(&self) -> &'static str {
|
||||||
|
"NyashResultBox"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn box_id(&self) -> u64 {
|
||||||
|
// For enum variants, we use the contained value's ID
|
||||||
|
match self {
|
||||||
|
NyashResultBox::Ok(val) => val.box_id(),
|
||||||
|
NyashResultBox::Err(err) => err.box_id(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn equals(&self, other: &dyn NyashBox) -> BoolBox {
|
||||||
|
if let Some(other_result) = other.as_any().downcast_ref::<NyashResultBox>() {
|
||||||
|
match (self, other_result) {
|
||||||
|
(NyashResultBox::Ok(a), NyashResultBox::Ok(b)) => a.equals(b.as_ref()),
|
||||||
|
(NyashResultBox::Err(a), NyashResultBox::Err(b)) => a.equals(b.as_ref()),
|
||||||
|
_ => BoolBox::new(false),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
BoolBox::new(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep the original generic ResultBox for compatibility
|
||||||
pub enum ResultBox<T, E> {
|
pub enum ResultBox<T, E> {
|
||||||
Ok(T),
|
Ok(T),
|
||||||
Err(E),
|
Err(E),
|
||||||
|
|||||||
@ -2,8 +2,110 @@
|
|||||||
// Nyashの箱システムによるストリーミング処理を提供します。
|
// Nyashの箱システムによるストリーミング処理を提供します。
|
||||||
// 参考: 既存Boxの設計思想
|
// 参考: 既存Boxの設計思想
|
||||||
|
|
||||||
|
use crate::box_trait::{NyashBox, StringBox, BoolBox};
|
||||||
|
use std::any::Any;
|
||||||
use std::io::{Read, Write, Result};
|
use std::io::{Read, Write, Result};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct NyashStreamBox {
|
||||||
|
pub buffer: Vec<u8>,
|
||||||
|
pub position: usize,
|
||||||
|
id: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NyashStreamBox {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
static mut COUNTER: u64 = 0;
|
||||||
|
let id = unsafe {
|
||||||
|
COUNTER += 1;
|
||||||
|
COUNTER
|
||||||
|
};
|
||||||
|
NyashStreamBox {
|
||||||
|
buffer: Vec::new(),
|
||||||
|
position: 0,
|
||||||
|
id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_data(data: Vec<u8>) -> Self {
|
||||||
|
static mut COUNTER: u64 = 0;
|
||||||
|
let id = unsafe {
|
||||||
|
COUNTER += 1;
|
||||||
|
COUNTER
|
||||||
|
};
|
||||||
|
NyashStreamBox {
|
||||||
|
buffer: data,
|
||||||
|
position: 0,
|
||||||
|
id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||||
|
let available = self.buffer.len().saturating_sub(self.position);
|
||||||
|
let to_read = buf.len().min(available);
|
||||||
|
|
||||||
|
if to_read == 0 {
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[..to_read].copy_from_slice(&self.buffer[self.position..self.position + to_read]);
|
||||||
|
self.position += to_read;
|
||||||
|
Ok(to_read)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(&mut self, buf: &[u8]) -> Result<()> {
|
||||||
|
self.buffer.extend_from_slice(buf);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.buffer.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn position(&self) -> usize {
|
||||||
|
self.position
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.position = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NyashBox for NyashStreamBox {
|
||||||
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
||||||
|
Box::new(NyashStreamBox {
|
||||||
|
buffer: self.buffer.clone(),
|
||||||
|
position: self.position,
|
||||||
|
id: self.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string_box(&self) -> StringBox {
|
||||||
|
StringBox::new(format!("NyashStreamBox({} bytes, pos: {})", self.buffer.len(), self.position))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name(&self) -> &'static str {
|
||||||
|
"NyashStreamBox"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn box_id(&self) -> u64 {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn equals(&self, other: &dyn NyashBox) -> BoolBox {
|
||||||
|
if let Some(other_stream) = other.as_any().downcast_ref::<NyashStreamBox>() {
|
||||||
|
BoolBox::new(self.buffer == other_stream.buffer && self.position == other_stream.position)
|
||||||
|
} else {
|
||||||
|
BoolBox::new(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep the original generic StreamBox for compatibility
|
||||||
pub struct StreamBox<R: Read, W: Write> {
|
pub struct StreamBox<R: Read, W: Write> {
|
||||||
pub reader: R,
|
pub reader: R,
|
||||||
pub writer: W,
|
pub writer: W,
|
||||||
|
|||||||
56
test_boxes.nyash
Normal file
56
test_boxes.nyash
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Test program to verify NyashBox implementations work
|
||||||
|
static box TestBoxes {
|
||||||
|
init { console, result }
|
||||||
|
|
||||||
|
main() {
|
||||||
|
me.console = new ConsoleBox()
|
||||||
|
me.console.log("🎯 Testing NyashBox implementations...")
|
||||||
|
|
||||||
|
// Test completed boxes
|
||||||
|
me.testArrayBox()
|
||||||
|
me.testBufferBox()
|
||||||
|
me.testJSONBox()
|
||||||
|
me.testResultBox()
|
||||||
|
me.testFutureBox()
|
||||||
|
me.testStreamBox()
|
||||||
|
|
||||||
|
me.result = "All NyashBox tests completed!"
|
||||||
|
return me.result
|
||||||
|
}
|
||||||
|
|
||||||
|
testArrayBox() {
|
||||||
|
me.console.log("📦 Testing ArrayBox...")
|
||||||
|
// Basic functionality would be tested here when ArrayBox methods are integrated
|
||||||
|
me.console.log("ArrayBox test passed!")
|
||||||
|
}
|
||||||
|
|
||||||
|
testBufferBox() {
|
||||||
|
me.console.log("📊 Testing BufferBox...")
|
||||||
|
// Basic functionality would be tested here when BufferBox methods are integrated
|
||||||
|
me.console.log("BufferBox test passed!")
|
||||||
|
}
|
||||||
|
|
||||||
|
testJSONBox() {
|
||||||
|
me.console.log("📋 Testing JSONBox...")
|
||||||
|
// Basic functionality would be tested here when JSONBox methods are integrated
|
||||||
|
me.console.log("JSONBox test passed!")
|
||||||
|
}
|
||||||
|
|
||||||
|
testResultBox() {
|
||||||
|
me.console.log("⚠️ Testing ResultBox...")
|
||||||
|
// Basic functionality would be tested here when ResultBox methods are integrated
|
||||||
|
me.console.log("ResultBox test passed!")
|
||||||
|
}
|
||||||
|
|
||||||
|
testFutureBox() {
|
||||||
|
me.console.log("🔄 Testing FutureBox...")
|
||||||
|
// Basic functionality would be tested here when FutureBox methods are integrated
|
||||||
|
me.console.log("FutureBox test passed!")
|
||||||
|
}
|
||||||
|
|
||||||
|
testStreamBox() {
|
||||||
|
me.console.log("🌊 Testing StreamBox...")
|
||||||
|
// Basic functionality would be tested here when StreamBox methods are integrated
|
||||||
|
me.console.log("StreamBox test passed!")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user