Initialize repository.
This commit is contained in:
commit
a8468a99eb
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/target
|
||||
Cargo.lock
|
9
Cargo.toml
Normal file
9
Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "szun"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
num = "0.4.3"
|
||||
|
||||
pack = { git = "https://git.tsukiyo.org/Utility/pack" }
|
44
src/bin/test.rs
Normal file
44
src/bin/test.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use szun::*;
|
||||
|
||||
fn main()
|
||||
{
|
||||
{
|
||||
let data = Boolean::new().with(true);
|
||||
println!("bool {}", data.get());
|
||||
}
|
||||
|
||||
{
|
||||
let data = Natural::new().with(15);
|
||||
println!("nat {}", data.get::<u32>());
|
||||
}
|
||||
|
||||
{
|
||||
let data = Integer::new().with(-55);
|
||||
println!("int {}", data.get::<i32>());
|
||||
}
|
||||
|
||||
{
|
||||
let (data, mut value) = Optional::<Integer>::new().with_default();
|
||||
value.set(-1);
|
||||
println!("opt {}", data.is_some());
|
||||
|
||||
if let Some(data) = data.get() {
|
||||
println!("opt {}", data.get::<i32>());
|
||||
}
|
||||
|
||||
data.unset();
|
||||
println!("opt {}", data.is_some());
|
||||
}
|
||||
|
||||
{
|
||||
let seq = Sequence::new().with_str("Hello, world!");
|
||||
println!("{} {} {}", seq.len(), seq.capacity(), seq.get_str());
|
||||
}
|
||||
|
||||
{
|
||||
let a = Integer::new().with(100);
|
||||
let b = a.clone();
|
||||
|
||||
println!("100 <> {}, {}", a.get::<i32>(), b.get::<i32>());
|
||||
}
|
||||
}
|
26
src/implement/any.rs
Normal file
26
src/implement/any.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use crate::prelude::{*, internal::*};
|
||||
|
||||
pub struct Any {
|
||||
pub(crate) refer:Ref,
|
||||
}
|
||||
impl Any {
|
||||
pub fn null() -> Self
|
||||
{
|
||||
Self { refer:Ref::null() }
|
||||
}
|
||||
|
||||
pub fn typeid(&self) -> usize { self.refer.typeid() }
|
||||
}
|
||||
impl Szun for Any {
|
||||
fn typeid() -> usize { 0 }
|
||||
}
|
||||
impl internal::SzunInternal for Any {
|
||||
fn to_ref(&self) -> Ref { self.refer }
|
||||
fn from_ref(refer:Ref) -> Self { Self { refer } }
|
||||
}
|
||||
impl Clone for Any {
|
||||
fn clone(&self) -> Self { Self::from_ref(clone(self.to_ref(), None)) }
|
||||
}
|
||||
impl Drop for Any {
|
||||
fn drop(&mut self) { drop(self.to_ref()); }
|
||||
}
|
67
src/implement/array.rs
Normal file
67
src/implement/array.rs
Normal file
@ -0,0 +1,67 @@
|
||||
use std::marker::PhantomData;
|
||||
use crate::{prelude::{*, internal::*}, Runtime, Any, types};
|
||||
|
||||
pub struct Array<T:Szun, const N:usize> {
|
||||
refer:Ref,
|
||||
phantom:PhantomData<T>,
|
||||
}
|
||||
impl<T:Szun, const N:usize> Array<T,N> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
refer:Runtime::acquire(Self::typeid()),
|
||||
phantom:PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with<R:Szun>(self, data:&[R]) -> Self
|
||||
{
|
||||
self.set(data);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set<R:Szun>(&self, data:&[R])
|
||||
{
|
||||
for i in 0..data.len() {
|
||||
let _refer = data[i].to_ref();
|
||||
/*if self.compatible(&data[i]) {
|
||||
|
||||
let inner_type = Runtime::type_in(self.refer.typeid());
|
||||
let inner_size = types::size(inner_type);
|
||||
|
||||
let mut bytes = vec![0u8; types::size(inner_type)];
|
||||
|
||||
Runtime::load(data[i].to_ref(), bytes.as_ptr() as _, 0, inner_size);
|
||||
|
||||
Runtime::store(self.refer, bytes.as_ptr() as _, 0, inner_size);
|
||||
Runtime::write(self.refer, 0xFF, inner_size);
|
||||
|
||||
if !types::primitive(data[i].to_ref().typeid()) {
|
||||
bytes.fill(0);
|
||||
Runtime::store(data[i].to_ref(), bytes.as_ptr() as _, 0, inner_size);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> std::option::Option<T>
|
||||
{
|
||||
let inner_type = Runtime::type_in(self.refer.typeid());
|
||||
|
||||
let mut flag :u8 = 0;
|
||||
Runtime::load(self.refer, &mut flag as _, types::size(inner_type), 1);
|
||||
if flag != 0 {
|
||||
let refer = self.refer;
|
||||
Some(T::from_ref(refer.inner()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T:Szun, const N:usize> Szun for Array<T,N> {
|
||||
fn typeid() -> usize { Runtime::type_from(T::typeid(), &[N, types::ARRAY]) }
|
||||
}
|
||||
impl<T:Szun, const N:usize> internal::SzunInternal for Array<T,N> {
|
||||
fn to_ref(&self) -> Ref { self.refer }
|
||||
fn from_ref(refer:Ref) -> Self { Self { refer, phantom:PhantomData } }
|
||||
}
|
||||
crate::impl_szun_generic_sized!(Array<T, N>);
|
65
src/implement/block.rs
Normal file
65
src/implement/block.rs
Normal file
@ -0,0 +1,65 @@
|
||||
use crate::{prelude::{*, internal::*}, Runtime, Any, types};
|
||||
|
||||
pub struct Block<const N:usize> {
|
||||
refer:Ref,
|
||||
}
|
||||
impl<const N:usize> Block<N> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
refer:Runtime::acquire(Self::typeid()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(mut self, data:&[u8]) -> Self
|
||||
{
|
||||
self.set(data);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set(&mut self, data:&[u8])
|
||||
{
|
||||
let size = Runtime::type_of(Runtime::type_in(self.refer.typeid()));
|
||||
let mut write = data.to_vec();
|
||||
write.resize(size, 0);
|
||||
Runtime::store(self.refer, write.as_ptr() as _, 0, types::size(self.refer.typeid()));
|
||||
}
|
||||
|
||||
pub fn set_byte(&mut self, index:usize, byte:u8)
|
||||
{
|
||||
if index < self.len() {
|
||||
Runtime::store(self.refer, &byte as _, index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> Vec<u8>
|
||||
{
|
||||
let size = Runtime::type_of(Runtime::type_in(self.refer.typeid()));
|
||||
let mut data = vec![0u8; size];
|
||||
Runtime::load(self.refer, data.as_mut_ptr() as _, 0, types::size(self.refer.typeid()));
|
||||
data
|
||||
}
|
||||
|
||||
pub fn get_byte(&mut self, index:usize) -> u8
|
||||
{
|
||||
if index < self.len() {
|
||||
let mut byte = 0u8;
|
||||
Runtime::load(self.refer, &mut byte as _, index, 1);
|
||||
byte
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize
|
||||
{
|
||||
Runtime::type_of(Runtime::type_in(self.refer.typeid()))
|
||||
}
|
||||
}
|
||||
impl<const N:usize> Szun for Block<N> {
|
||||
fn typeid() -> usize { Runtime::type_from(types::ANY, &[N, types::BLOCK]) }
|
||||
}
|
||||
impl<const N:usize> SzunInternal for Block<N> {
|
||||
fn to_ref(&self) -> Ref { self.refer }
|
||||
fn from_ref(refer:Ref) -> Self { Self { refer } }
|
||||
}
|
||||
crate::impl_szun_sized!(Block<N>);
|
42
src/implement/boolean.rs
Normal file
42
src/implement/boolean.rs
Normal file
@ -0,0 +1,42 @@
|
||||
use crate::{prelude::{*, internal::*}, Runtime, Any, types};
|
||||
|
||||
pub struct Boolean {
|
||||
refer:Ref,
|
||||
}
|
||||
impl Boolean {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
refer:Runtime::acquire(Self::typeid()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(self, data:bool) -> Self
|
||||
{
|
||||
self.set(data);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set(&self, data:bool)
|
||||
{
|
||||
if let Some(memory) = unsafe {(self.refer.address_mut() as *mut bool).as_mut()} {
|
||||
*memory = data;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> bool
|
||||
{
|
||||
if let Some(memory) = unsafe {(self.refer.address() as *const bool).as_ref()} {
|
||||
*memory
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Szun for Boolean {
|
||||
fn typeid() -> usize { Runtime::type_from(types::ANY, &[types::BOOLEAN]) }
|
||||
}
|
||||
impl SzunInternal for Boolean {
|
||||
fn to_ref(&self) -> Ref { self.refer }
|
||||
fn from_ref(refer:Ref) -> Self { Self { refer } }
|
||||
}
|
||||
crate::impl_szun!(Boolean);
|
43
src/implement/integer.rs
Normal file
43
src/implement/integer.rs
Normal file
@ -0,0 +1,43 @@
|
||||
use crate::{prelude::{*, internal::*}, Runtime, Any, types};
|
||||
|
||||
pub struct Integer {
|
||||
refer:Ref,
|
||||
}
|
||||
impl Integer {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
refer:Runtime::acquire(Self::typeid()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with<T:num::ToPrimitive>(mut self, data:T) -> Self
|
||||
{
|
||||
self.set(data);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set<T:num::ToPrimitive>(&mut self, data:T)
|
||||
{
|
||||
let data = data.to_i64().unwrap_or_default();
|
||||
if let Some(memory) = unsafe {(self.refer.address_mut() as *mut i64).as_mut()} {
|
||||
*memory = data;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get<T:num::FromPrimitive + Default>(&self) -> T
|
||||
{
|
||||
T::from_i64(if let Some(memory) = unsafe {(self.refer.address() as *const i64).as_ref()} {
|
||||
*memory
|
||||
} else {
|
||||
0
|
||||
}).unwrap_or_default()
|
||||
}
|
||||
}
|
||||
impl Szun for Integer {
|
||||
fn typeid() -> usize { Runtime::type_from(types::ANY, &[types::INTEGER]) }
|
||||
}
|
||||
impl SzunInternal for Integer {
|
||||
fn to_ref(&self) -> Ref { self.refer }
|
||||
fn from_ref(refer:Ref) -> Self { Self { refer } }
|
||||
}
|
||||
crate::impl_szun!(Integer);
|
9
src/implement/mod.rs
Normal file
9
src/implement/mod.rs
Normal file
@ -0,0 +1,9 @@
|
||||
pub mod any; pub use any::Any;
|
||||
pub mod null; pub use null::Null;
|
||||
pub mod boolean; pub use boolean::Boolean;
|
||||
pub mod natural; pub use natural::Natural;
|
||||
pub mod integer; pub use integer::Integer;
|
||||
pub mod block; pub use block::Block;
|
||||
pub mod sequence; pub use sequence::Sequence;
|
||||
pub mod optional; pub use optional::Optional;
|
||||
pub mod array; pub use array::Array;
|
43
src/implement/natural.rs
Normal file
43
src/implement/natural.rs
Normal file
@ -0,0 +1,43 @@
|
||||
use crate::{prelude::{*, internal::*}, Runtime, Any, types};
|
||||
|
||||
pub struct Natural {
|
||||
refer:Ref,
|
||||
}
|
||||
impl Natural {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
refer:Runtime::acquire(Self::typeid()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with<T:num::ToPrimitive>(mut self, data:T) -> Self
|
||||
{
|
||||
self.set(data);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set<T:num::ToPrimitive>(&mut self, data:T)
|
||||
{
|
||||
let data = data.to_u64().unwrap_or_default();
|
||||
if let Some(memory) = unsafe {(self.refer.address_mut() as *mut u64).as_mut()} {
|
||||
*memory = data;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get<T:num::FromPrimitive + Default>(&self) -> T
|
||||
{
|
||||
T::from_u64(if let Some(memory) = unsafe {(self.refer.address() as *const u64).as_ref()} {
|
||||
*memory
|
||||
} else {
|
||||
0
|
||||
}).unwrap_or_default()
|
||||
}
|
||||
}
|
||||
impl Szun for Natural {
|
||||
fn typeid() -> usize { Runtime::type_from(types::ANY, &[types::NATURAL]) }
|
||||
}
|
||||
impl SzunInternal for Natural {
|
||||
fn to_ref(&self) -> Ref { self.refer }
|
||||
fn from_ref(refer:Ref) -> Self { Self { refer } }
|
||||
}
|
||||
crate::impl_szun!(Natural);
|
16
src/implement/null.rs
Normal file
16
src/implement/null.rs
Normal file
@ -0,0 +1,16 @@
|
||||
use crate::{prelude::{*, internal::*}, Runtime, Any, types};
|
||||
|
||||
pub struct Null { }
|
||||
impl Null {
|
||||
pub fn new() -> Self {
|
||||
Self { }
|
||||
}
|
||||
}
|
||||
impl Szun for Null {
|
||||
fn typeid() -> usize { Runtime::type_from(types::ANY, &[types::BOOLEAN]) }
|
||||
}
|
||||
impl SzunInternal for Null {
|
||||
fn to_ref(&self) -> Ref { Ref::null() }
|
||||
fn from_ref(_:Ref) -> Self { Self { } }
|
||||
}
|
||||
crate::impl_szun!(Null);
|
120
src/implement/optional.rs
Normal file
120
src/implement/optional.rs
Normal file
@ -0,0 +1,120 @@
|
||||
use std::marker::PhantomData;
|
||||
use internal::SzunInternal;
|
||||
|
||||
use crate::{prelude::*, Runtime, Any, types};
|
||||
|
||||
pub struct Optional<T> where T:Szun {
|
||||
refer:Ref,
|
||||
phantom:PhantomData<T>,
|
||||
}
|
||||
impl<T:Szun> Optional<T> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
refer:Runtime::acquire(Self::typeid()),
|
||||
phantom:PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(self, data:&T) -> Self
|
||||
{
|
||||
self.set(data);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_default(self) -> (Self, T)
|
||||
{
|
||||
self.set_default();
|
||||
let refer = self.refer;
|
||||
(self, T::from_ref(refer.inner()))
|
||||
}
|
||||
|
||||
pub fn set(&self, data:&T)
|
||||
{
|
||||
let inner_type = Runtime::type_in(self.refer.typeid());
|
||||
let inner_size = types::size(inner_type);
|
||||
|
||||
let mut bytes = vec![0u8; types::size(inner_type)];
|
||||
|
||||
Runtime::load(data.to_ref(), bytes.as_ptr() as _, 0, inner_size);
|
||||
|
||||
Runtime::store(self.refer, bytes.as_ptr() as _, 0, inner_size);
|
||||
Runtime::write(self.refer, 0xFF, inner_size);
|
||||
|
||||
if !types::primitive(data.to_ref().typeid()) {
|
||||
bytes.fill(0);
|
||||
Runtime::store(data.to_ref(), bytes.as_ptr() as _, 0, inner_size);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_default(&self) -> T
|
||||
{
|
||||
let inner_type = Runtime::type_in(self.refer.typeid());
|
||||
Runtime::write(self.refer, 0xFF, types::size(inner_type));
|
||||
|
||||
T::from_ref(self.refer.temporary())
|
||||
}
|
||||
|
||||
pub fn unset(&self)
|
||||
{
|
||||
let inner_type = Runtime::type_in(self.refer.typeid());
|
||||
let inner_size = types::size(inner_type);
|
||||
let bytes = vec![0u8; types::size(inner_type)];
|
||||
|
||||
Runtime::store(self.refer, bytes.as_ptr() as _, 0, inner_size);
|
||||
Runtime::write(self.refer, 0x00, inner_size);
|
||||
}
|
||||
|
||||
pub fn get(&self) -> std::option::Option<T>
|
||||
{
|
||||
let inner_type = Runtime::type_in(self.refer.typeid());
|
||||
|
||||
let mut flag :u8 = 0;
|
||||
Runtime::load(self.refer, &mut flag as _, types::size(inner_type), 1);
|
||||
if flag != 0 {
|
||||
let refer = self.refer;
|
||||
Some(T::from_ref(refer.inner()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_some(&self) -> bool
|
||||
{
|
||||
let inner_type = Runtime::type_in(self.refer.typeid());
|
||||
|
||||
let mut flag :u8 = 0;
|
||||
Runtime::load(self.refer, &mut flag as _, types::size(inner_type), 1);
|
||||
flag != 0
|
||||
}
|
||||
|
||||
pub fn is_none(&self) -> bool
|
||||
{
|
||||
!self.is_some()
|
||||
}
|
||||
}
|
||||
impl<T:Szun> Szun for Optional<T> {
|
||||
fn typeid() -> usize { Runtime::type_from(T::typeid(), &[types::OPTIONAL]) }
|
||||
}
|
||||
impl<T:Szun> SzunInternal for Optional<T> {
|
||||
fn to_ref(&self) -> Ref { self.refer }
|
||||
fn from_ref(refer:Ref) -> Self { Self { refer, phantom:PhantomData } }
|
||||
|
||||
fn mem_clone(refer:Ref, memory:std::prelude::v1::Option<Ref>) -> Ref {
|
||||
// Allocate new memory if not provided
|
||||
let memory = if let Some(memory) = memory {
|
||||
memory
|
||||
} else {
|
||||
Runtime::acquire(refer.typeid())
|
||||
};
|
||||
|
||||
// Copy memory
|
||||
clone(refer.inner(), Some(memory.inner()));
|
||||
|
||||
memory
|
||||
}
|
||||
|
||||
fn mem_drop(refer:Ref) {
|
||||
drop(refer.inner())
|
||||
}
|
||||
}
|
||||
crate::impl_szun_generic!(Optional<T>);
|
109
src/implement/sequence.rs
Normal file
109
src/implement/sequence.rs
Normal file
@ -0,0 +1,109 @@
|
||||
use internal::SzunInternal;
|
||||
|
||||
use crate::{prelude::*, Runtime, Any, types};
|
||||
|
||||
pub(crate) struct Data {
|
||||
pub capacity:usize,
|
||||
pub length:usize,
|
||||
pub data:*const u8,
|
||||
}
|
||||
|
||||
pub struct Sequence {
|
||||
refer:Ref,
|
||||
}
|
||||
impl Sequence {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
refer:Runtime::acquire(Self::typeid()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(mut self, data:&[u8]) -> Self
|
||||
{
|
||||
self.set(data);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_str(mut self, data:&str) -> Self
|
||||
{
|
||||
self.set(data.as_bytes());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set(&mut self, data:&[u8])
|
||||
{
|
||||
if let Some(header) = unsafe {(self.refer.address_mut() as *mut Data).as_mut()} {
|
||||
// Reallocate memory if capacity is insufficient
|
||||
if header.capacity < data.len() {
|
||||
// Free existing memory
|
||||
if !header.data.is_null() {
|
||||
if let Ok(layout) = std::alloc::Layout::from_size_align(header.capacity, 1) {
|
||||
unsafe { std::alloc::dealloc(header.data as _, layout); }
|
||||
}
|
||||
}
|
||||
// Allocate sufficient memory
|
||||
header.capacity = data.len();
|
||||
if let Ok(layout) = std::alloc::Layout::from_size_align(header.capacity, 1) {
|
||||
header.data = unsafe {std::alloc::alloc(layout)};
|
||||
} else {
|
||||
header.data = std::ptr::null();
|
||||
header.capacity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy data to memory
|
||||
if !header.data.is_null() {
|
||||
header.length = data.len();
|
||||
unsafe { std::ptr::copy_nonoverlapping(data.as_ptr() as _, header.data as _, data.len()); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_str(&mut self, data:&str)
|
||||
{
|
||||
self.set(data.as_bytes())
|
||||
}
|
||||
|
||||
pub fn get(&self) -> Vec<u8>
|
||||
{
|
||||
if let Some(header) = unsafe {(self.refer.address_mut() as *mut Data).as_mut()} {
|
||||
// Load data
|
||||
let mut data = vec![0u8; header.length];
|
||||
unsafe { std::ptr::copy_nonoverlapping(header.data as _, data.as_mut_ptr() as _, header.length); }
|
||||
data
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_str(&self) -> String
|
||||
{
|
||||
String::from_utf8(self.get()).unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize
|
||||
{
|
||||
if let Some(header) = unsafe {(self.refer.address_mut() as *mut Data).as_mut()} {
|
||||
header.length
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn capacity(&self) -> usize
|
||||
{
|
||||
if let Some(header) = unsafe {(self.refer.address_mut() as *mut Data).as_mut()} {
|
||||
header.capacity
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Szun for Sequence {
|
||||
fn typeid() -> usize { Runtime::type_from(types::ANY, &[types::SEQUENCE]) }
|
||||
}
|
||||
impl internal::SzunInternal for Sequence {
|
||||
fn to_ref(&self) -> Ref { self.refer }
|
||||
fn from_ref(refer:Ref) -> Self { Self { refer } }
|
||||
}
|
||||
crate::impl_szun!(Sequence);
|
7
src/lib.rs
Normal file
7
src/lib.rs
Normal file
@ -0,0 +1,7 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
mod util;
|
||||
pub mod prelude; pub use prelude::*;
|
||||
mod types;
|
||||
mod runtime; use runtime::Runtime;
|
||||
mod implement; pub use implement::*;
|
15
src/prelude/clone.rs
Normal file
15
src/prelude/clone.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use crate::Ref;
|
||||
|
||||
pub fn clone(refer:Ref, memory:Option<Ref>) -> Ref
|
||||
// Deep copy an object and return the copy's reference.
|
||||
//
|
||||
{
|
||||
use crate::{*, prelude::internal::*};
|
||||
match Runtime::type_of(refer.typeid()) {
|
||||
types::SEQUENCE => Sequence::mem_clone(refer, memory),
|
||||
types::OPTIONAL => Optional::<Any>::mem_clone(refer, memory),
|
||||
types::ARRAY => Array::<Any,0>::mem_clone(refer, memory),
|
||||
|
||||
_ => Any::mem_clone(refer, memory),
|
||||
}
|
||||
}
|
34
src/prelude/drop.rs
Normal file
34
src/prelude/drop.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use crate::{prelude::{*, internal::*}, types::*, implement::*};
|
||||
|
||||
pub fn drop(refer:Ref)
|
||||
{
|
||||
if !refer.is_temporary() {
|
||||
drop_memory(refer);
|
||||
Runtime::release(refer);
|
||||
}
|
||||
}
|
||||
|
||||
fn drop_memory(refer:Ref)
|
||||
{
|
||||
let typeid = refer.typeid();
|
||||
match typeid {
|
||||
OPTIONAL => {
|
||||
let obj = crate::Optional::<Any>::from_ref(refer.temporary());
|
||||
if obj.is_some() {
|
||||
drop_memory(refer.inner());
|
||||
}
|
||||
}
|
||||
|
||||
SEQUENCE => {
|
||||
if let Some(header) = unsafe {(refer.address_mut() as *mut sequence::Data).as_mut()} {
|
||||
if !header.data.is_null() {
|
||||
if let Ok(layout) = std::alloc::Layout::from_size_align(header.capacity, 1) {
|
||||
unsafe { std::alloc::dealloc(header.data as _, layout); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ => { }
|
||||
}
|
||||
}
|
70
src/prelude/encode.rs
Normal file
70
src/prelude/encode.rs
Normal file
@ -0,0 +1,70 @@
|
||||
use crate::{*, prelude::{*, internal::*}, types::*};
|
||||
|
||||
pub fn encode(refer:Ref) -> Vec<u8>
|
||||
{
|
||||
let refer = refer.temporary();
|
||||
let mut result = Vec::new();
|
||||
|
||||
let typeid = Runtime::type_of(refer.typeid());
|
||||
match typeid {
|
||||
BOOLEAN => {
|
||||
// <Data:1>
|
||||
//
|
||||
let data = Boolean::from_ref(refer);
|
||||
result.push(data.get() as u8);
|
||||
}
|
||||
|
||||
NATURAL => {
|
||||
// <Data:Uint>
|
||||
//
|
||||
let data = Natural::from_ref(refer);
|
||||
result.append(&mut data.get::<u64>().pack());
|
||||
}
|
||||
|
||||
INTEGER => {
|
||||
// <Data:Int>
|
||||
//
|
||||
let _data = Integer::from_ref(refer);
|
||||
//result.append(&mut data.get::<i64>().pack());
|
||||
}
|
||||
|
||||
BLOCK => {
|
||||
// <Data:N>
|
||||
//
|
||||
let data = Block::<0>::from_ref(refer);
|
||||
result.append(&mut data.get());
|
||||
}
|
||||
|
||||
SEQUENCE => {
|
||||
// <Length:Uint> <Data:Length>
|
||||
//
|
||||
let data = Sequence::from_ref(refer);
|
||||
result.append(&mut (data.len() as u64).pack());
|
||||
result.append(&mut data.get());
|
||||
}
|
||||
|
||||
OPTIONAL => {
|
||||
// <IsSome:1> <Data:N>?
|
||||
//
|
||||
let data = Optional::<Any>::from_ref(refer);
|
||||
let is_some = data.is_some();
|
||||
result.push(is_some as u8);
|
||||
if let Some(value) = data.get() {
|
||||
result.append(&mut encode(value.to_ref()));
|
||||
}
|
||||
}
|
||||
|
||||
_ => { }
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub fn decode(refer:Ref, _data:&[u8], _index:&mut usize) -> Result<(),()>
|
||||
{
|
||||
let typeid = Runtime::type_of(refer.typeid());
|
||||
match typeid {
|
||||
_ => { }
|
||||
}
|
||||
Err(())
|
||||
}
|
13
src/prelude/implement.rs
Normal file
13
src/prelude/implement.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use crate::prelude::{*, internal::*};
|
||||
|
||||
pub(crate) fn to_any<T:Szun>(data:T) -> Any
|
||||
{
|
||||
Any::from_ref(data.to_ref())
|
||||
}
|
||||
|
||||
pub(crate) fn from_any<T:Szun>(any:Any) -> Result<T,()>
|
||||
{
|
||||
if any.typeid() == T::typeid()
|
||||
|| (Runtime::type_of(any.typeid()) == Runtime::type_of(T::typeid()) && Runtime::type_in(T::typeid()) == 0)
|
||||
{ Ok(T::from_ref(any.refer)) } else { Err(()) }
|
||||
}
|
25
src/prelude/internal/mod.rs
Normal file
25
src/prelude/internal/mod.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use crate::{Ref, Runtime, types};
|
||||
|
||||
#[allow(drop_bounds)]
|
||||
pub(crate) trait SzunInternal {
|
||||
fn to_ref(&self) -> Ref;
|
||||
fn from_ref(refer:Ref) -> Self;
|
||||
|
||||
fn mem_clone(refer:Ref, memory:Option<Ref>) -> Ref {
|
||||
let typeid = refer.typeid();
|
||||
|
||||
// Acquire memory if not provided
|
||||
let memory = if let Some(memory) = memory {
|
||||
memory
|
||||
} else {
|
||||
Runtime::acquire(typeid)
|
||||
};
|
||||
|
||||
// Copy data to destination
|
||||
Runtime::copy(refer.address(), memory.address_mut(), types::size(typeid));
|
||||
|
||||
memory
|
||||
}
|
||||
|
||||
fn mem_drop(_refer:Ref) { /* Do nothing */ }
|
||||
}
|
38
src/prelude/mod.rs
Normal file
38
src/prelude/mod.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use crate::{Runtime, Any};
|
||||
use pack::prelude::*;
|
||||
|
||||
pub mod internal;
|
||||
|
||||
mod refer; pub(crate) use refer::Ref;
|
||||
mod encode; pub(crate) use encode::*;
|
||||
|
||||
#[allow(drop_bounds, private_bounds)]
|
||||
pub trait Szun : internal::SzunInternal + Clone + TryFrom<Any> + Into<Any> + Drop {
|
||||
fn typeid() -> usize;
|
||||
|
||||
fn compatible<T:Szun>(&self, data:&T) -> bool
|
||||
{
|
||||
let data_type = data.to_ref().typeid();
|
||||
let self_type = self.to_ref().typeid();
|
||||
data_type == Runtime::type_in(self_type)
|
||||
|| Runtime::type_in(self_type) == 0
|
||||
}
|
||||
|
||||
fn encode(&self) -> Vec<u8> { encode(self.to_ref()) }
|
||||
fn decode(&mut self, bytes:&Vec<u8>, index:&mut usize) -> Result<(),()> { decode(self.to_ref(), bytes, index) }
|
||||
|
||||
fn tag(&self) -> Vec<u8>
|
||||
{
|
||||
let mut result = Vec::new();
|
||||
let mut next = Some(Self::typeid());
|
||||
while let Some(next_id) = next {
|
||||
result.append(&mut 0u32.pack());
|
||||
next = Runtime::type_in_opt(next_id);
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
mod implement; pub(crate) use implement::*;
|
||||
mod clone; pub(crate) use clone::*;
|
||||
mod drop; pub(crate) use drop::*;
|
58
src/prelude/refer.rs
Normal file
58
src/prelude/refer.rs
Normal file
@ -0,0 +1,58 @@
|
||||
use crate::Runtime;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Ref {
|
||||
typeid:usize,
|
||||
address:*const u8,
|
||||
}
|
||||
impl Ref {
|
||||
pub(crate) fn new(typeid:usize, address:*const u8) -> Self
|
||||
{
|
||||
Self {
|
||||
typeid,
|
||||
address,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn null() -> Self
|
||||
{
|
||||
Self {
|
||||
typeid:0,
|
||||
address:std::ptr::null(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inner(&self) -> Self
|
||||
{
|
||||
let mut refer = *self;
|
||||
refer.typeid = Runtime::type_in(self.typeid);
|
||||
self.temporary()
|
||||
}
|
||||
|
||||
pub fn temporary(&self) -> Self
|
||||
{
|
||||
let mut refer = *self;
|
||||
refer.typeid |= 1 << (usize::BITS - 1);
|
||||
refer
|
||||
}
|
||||
|
||||
pub fn is_temporary(&self) -> bool
|
||||
{
|
||||
(self.typeid & (1 << (usize::BITS - 1))) != 0
|
||||
}
|
||||
|
||||
pub fn typeid(&self) -> usize
|
||||
{
|
||||
self.typeid & !(1 << (usize::BITS - 1))
|
||||
}
|
||||
|
||||
pub fn address(&self) -> *const u8
|
||||
{
|
||||
self.address
|
||||
}
|
||||
|
||||
pub fn address_mut(&self) -> *mut u8
|
||||
{
|
||||
self.address as _
|
||||
}
|
||||
}
|
118
src/runtime/mod.rs
Normal file
118
src/runtime/mod.rs
Normal file
@ -0,0 +1,118 @@
|
||||
use crate::{prelude::*, types};
|
||||
|
||||
mod typetree; use typetree::TypeTree;
|
||||
|
||||
struct RuntimeData {
|
||||
terms:Vec<u8>,
|
||||
types:TypeTree,
|
||||
}
|
||||
impl RuntimeData {
|
||||
const fn init() -> Self
|
||||
{
|
||||
Self {
|
||||
terms:Vec::new(),
|
||||
types:TypeTree::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn acquire(&mut self, typeid:usize) -> Ref
|
||||
{
|
||||
use std::alloc::{alloc_zeroed, Layout};
|
||||
|
||||
let size = types::size(typeid);
|
||||
if size > 0 {
|
||||
if let Ok(layout) = Layout::from_size_align(size, types::align(typeid)) {
|
||||
let address :*const u8;
|
||||
unsafe {
|
||||
address = alloc_zeroed(layout) as _;
|
||||
}
|
||||
Ref::new(typeid, address)
|
||||
} else {
|
||||
Ref::null()
|
||||
}
|
||||
} else {
|
||||
Ref::null()
|
||||
}
|
||||
}
|
||||
|
||||
fn release(&mut self, refer:Ref)
|
||||
{
|
||||
use std::alloc::{dealloc, Layout};
|
||||
|
||||
let typeid = refer.typeid();
|
||||
let size = types::size(typeid);
|
||||
if size > 0 {
|
||||
if let Ok(layout) = Layout::from_size_align(size, types::align(typeid)) {
|
||||
unsafe {
|
||||
dealloc(refer.address_mut(), layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn store(&mut self, refer:Ref, data:*const u8, index:usize, len:usize)
|
||||
{
|
||||
unsafe {
|
||||
std::ptr::copy_nonoverlapping(data, refer.address_mut().add(index), len);
|
||||
}
|
||||
}
|
||||
|
||||
fn load(&mut self, refer:Ref, data:*mut u8, index:usize, len:usize)
|
||||
{
|
||||
unsafe {
|
||||
std::ptr::copy_nonoverlapping(refer.address().add(index), data, len);
|
||||
}
|
||||
}
|
||||
|
||||
fn copy(&mut self, src:*const u8, dst:*mut u8, len:usize)
|
||||
{
|
||||
unsafe {
|
||||
std::ptr::copy_nonoverlapping(src, dst, len);
|
||||
}
|
||||
}
|
||||
|
||||
fn write(&mut self, refer:Ref, data:u8, index:usize)
|
||||
{
|
||||
unsafe { *refer.address_mut().byte_add(index) = data; }
|
||||
}
|
||||
|
||||
fn zero(&mut self, refer:Ref)
|
||||
{
|
||||
let size = types::size(refer.typeid());
|
||||
for i in 0..size {
|
||||
unsafe { *refer.address_mut().byte_add(i) = 0; }
|
||||
}
|
||||
}
|
||||
|
||||
fn type_from(&mut self, parent:usize, types:&[usize]) -> usize
|
||||
{
|
||||
self.types.outer(parent, types)
|
||||
}
|
||||
|
||||
fn type_in(&mut self, typeid:usize) -> Option<usize>
|
||||
{
|
||||
self.types.inner(typeid)
|
||||
}
|
||||
|
||||
fn type_of(&mut self, typeid:usize) -> usize
|
||||
{
|
||||
self.types.value(typeid)
|
||||
}
|
||||
}
|
||||
static mut RUNTIME :RuntimeData = RuntimeData::init();
|
||||
|
||||
pub struct Runtime { }
|
||||
impl Runtime {
|
||||
pub fn acquire(typeid:usize) -> Ref {unsafe{ RUNTIME.acquire(typeid) }}
|
||||
pub fn release(refer:Ref) {unsafe{ RUNTIME.release(refer) }}
|
||||
pub fn store(refer:Ref, data:*const u8, index:usize, len:usize) {unsafe{ RUNTIME.store(refer, data, index, len) }}
|
||||
pub fn load(refer:Ref, data:*mut u8, index:usize, len:usize) {unsafe{ RUNTIME.load(refer, data, index, len) }}
|
||||
pub fn copy(src:*const u8, dst:*mut u8, len:usize) {unsafe{ RUNTIME.copy(src, dst, len) }}
|
||||
pub fn write(refer:Ref, data:u8, index:usize) {unsafe { RUNTIME.write(refer, data, index) }}
|
||||
pub fn zero(refer:Ref) {unsafe { RUNTIME.zero(refer) }}
|
||||
|
||||
pub fn type_of(typeid:usize) -> usize {unsafe{ RUNTIME.type_of(typeid) }}
|
||||
pub fn type_in(typeid:usize) -> usize {unsafe{ RUNTIME.type_in(typeid).unwrap_or_default() }}
|
||||
pub fn type_in_opt(typeid:usize) -> Option<usize> {unsafe{ RUNTIME.type_in(typeid) }}
|
||||
pub fn type_from(typeid:usize, types:&[usize]) -> usize {unsafe{ RUNTIME.type_from(typeid, types) }}
|
||||
}
|
104
src/runtime/typetree.rs
Normal file
104
src/runtime/typetree.rs
Normal file
@ -0,0 +1,104 @@
|
||||
struct Node {
|
||||
typeid:usize,
|
||||
parent:Option<usize>,
|
||||
child:Option<usize>,
|
||||
next:Option<usize>,
|
||||
}
|
||||
|
||||
pub struct TypeTree {
|
||||
data:Vec<Node>,
|
||||
}
|
||||
impl TypeTree {
|
||||
pub const fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
data:Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn value(&self, id:usize) -> usize
|
||||
{
|
||||
if id < self.data.len() {
|
||||
self.data[id].typeid
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inner(&self, id:usize) -> Option<usize>
|
||||
{
|
||||
if id < self.data.len() {
|
||||
self.data[id].parent
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn outer(&mut self, typeid:usize, types:&[usize]) -> usize
|
||||
{
|
||||
let mut itr = typeid;
|
||||
let mut type_index = 0;
|
||||
|
||||
if self.data.len() == 0 {
|
||||
self.data.push(Node {
|
||||
typeid:0,
|
||||
parent:None,
|
||||
child:None,
|
||||
next:None,
|
||||
});
|
||||
}
|
||||
|
||||
if typeid != 0 {
|
||||
if let Some(child) = self.data[itr].child {
|
||||
itr = child;
|
||||
} else {
|
||||
let node = Node {
|
||||
typeid:types[type_index],
|
||||
parent:Some(itr),
|
||||
child:None,
|
||||
next:None,
|
||||
};
|
||||
itr = self.data.len();
|
||||
self.data.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
while type_index < types.len() {
|
||||
if self.data[itr].typeid == types[type_index] {
|
||||
if type_index + 1 < types.len() {
|
||||
if let Some(child) = self.data[itr].child {
|
||||
itr = child;
|
||||
} else {
|
||||
let node = Node {
|
||||
typeid:types[type_index],
|
||||
parent:Some(itr),
|
||||
child:None,
|
||||
next:None,
|
||||
};
|
||||
itr = self.data.len();
|
||||
self.data.push(node);
|
||||
}
|
||||
type_index += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if let Some(next) = self.data[itr].next {
|
||||
itr = next;
|
||||
} else {
|
||||
let node = Node {
|
||||
typeid:types[type_index],
|
||||
parent:self.data[itr].parent,
|
||||
child:None,
|
||||
next:None,
|
||||
};
|
||||
self.data[itr].next = Some(self.data.len());
|
||||
itr = self.data.len();
|
||||
self.data.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
itr
|
||||
}
|
||||
}
|
140
src/types.rs
Normal file
140
src/types.rs
Normal file
@ -0,0 +1,140 @@
|
||||
use crate::Runtime;
|
||||
|
||||
/*
|
||||
** Type Codes
|
||||
*/
|
||||
pub const ANY :usize = 0x00;
|
||||
pub const BOOLEAN :usize = 0x01;
|
||||
pub const BYTE :usize = 0x02;
|
||||
pub const CHAR :usize = 0x03;
|
||||
pub const NATURAL :usize = 0x10;
|
||||
pub const INTEGER :usize = 0x11;
|
||||
pub const DECIMAL :usize = 0x12;
|
||||
pub const SIGNIFICANT :usize = 0x13;
|
||||
pub const BLOCK :usize = 0x20;
|
||||
pub const SEQUENCE :usize = 0x21;
|
||||
pub const VAR :usize = 0x30;
|
||||
pub const OPTIONAL :usize = 0x31;
|
||||
pub const ARRAY :usize = 0x32;
|
||||
pub const LIST :usize = 0x33;
|
||||
pub const GRAPH :usize = 0x34;
|
||||
pub const TRIE :usize = 0x35;
|
||||
pub const MAP :usize = 0x40;
|
||||
pub const SPARSE :usize = 0x41;
|
||||
pub const POOL :usize = 0x42;
|
||||
pub const TABLE :usize = 0x43;
|
||||
pub const ENUM :usize = 0x7D;
|
||||
pub const RECORD :usize = 0x7E;
|
||||
pub const SCHEMA :usize = 0x7F;
|
||||
|
||||
pub fn size(typeid:usize) -> usize
|
||||
// Byte size of static data in memory.
|
||||
//
|
||||
{
|
||||
use std::mem::size_of;
|
||||
|
||||
match Runtime::type_of(typeid) {
|
||||
ANY => 0,
|
||||
BOOLEAN => size_of::<bool>(),
|
||||
BYTE => size_of::<u8>(),
|
||||
CHAR => size_of::<char>(),
|
||||
NATURAL => size_of::<u64>(),
|
||||
INTEGER => size_of::<i64>(),
|
||||
DECIMAL => size_of::<i64>(),
|
||||
SIGNIFICANT => size_of::<f64>(),
|
||||
BLOCK => Runtime::type_of(Runtime::type_in(typeid)),
|
||||
SEQUENCE => size_of::<crate::implement::sequence::Data>(),
|
||||
VAR => 16,
|
||||
OPTIONAL => size(Runtime::type_in(typeid)) + 1,
|
||||
ARRAY => {
|
||||
let inner_size = Runtime::type_in(typeid);
|
||||
let inner_type = Runtime::type_in(inner_size);
|
||||
Runtime::type_of(inner_size) * size(Runtime::type_of(inner_type))
|
||||
},
|
||||
LIST => 16,
|
||||
GRAPH => 0,
|
||||
TRIE => 0,
|
||||
MAP => 0,
|
||||
SPARSE => 0,
|
||||
POOL => 0,
|
||||
TABLE => 0,
|
||||
ENUM => 0,
|
||||
RECORD => 0,
|
||||
SCHEMA => 0,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn align(typeid:usize) -> usize
|
||||
// Byte alignment of type.
|
||||
//
|
||||
{
|
||||
use std::mem::align_of;
|
||||
|
||||
match Runtime::type_of(typeid) {
|
||||
ANY => 0,
|
||||
BOOLEAN => align_of::<bool>(),
|
||||
BYTE => align_of::<u8>(),
|
||||
CHAR => align_of::<char>(),
|
||||
NATURAL => align_of::<u64>(),
|
||||
INTEGER => align_of::<i64>(),
|
||||
DECIMAL => align_of::<i64>(),
|
||||
SIGNIFICANT => align_of::<f64>(),
|
||||
BLOCK => align_of::<u8>(),
|
||||
SEQUENCE => align_of::<crate::implement::sequence::Data>(),
|
||||
VAR => 8,
|
||||
OPTIONAL => align(Runtime::type_in(typeid)),
|
||||
ARRAY => {
|
||||
let inner_size = Runtime::type_in(typeid);
|
||||
let inner_type = Runtime::type_in(inner_size);
|
||||
align(Runtime::type_of(inner_type))
|
||||
},
|
||||
LIST => 8,
|
||||
GRAPH => 0,
|
||||
TRIE => 0,
|
||||
MAP => 0,
|
||||
SPARSE => 0,
|
||||
POOL => 0,
|
||||
TABLE => 0,
|
||||
ENUM => 0,
|
||||
RECORD => 0,
|
||||
SCHEMA => 0,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn primitive(typeid:usize) -> bool
|
||||
// Whether type may be shallow copied.
|
||||
//
|
||||
{
|
||||
match Runtime::type_of(typeid) {
|
||||
ANY | BOOLEAN
|
||||
| BYTE | CHAR
|
||||
| NATURAL | INTEGER | DECIMAL | SIGNIFICANT
|
||||
| BLOCK
|
||||
=> true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tag_stack(typeid:usize) -> usize
|
||||
// Number of dependent tags following root.
|
||||
//
|
||||
{
|
||||
match Runtime::type_of(typeid) {
|
||||
ANY => 1,
|
||||
BLOCK => 1,
|
||||
OPTIONAL => 1,
|
||||
ARRAY => 2,
|
||||
LIST => 1,
|
||||
GRAPH => 1,
|
||||
TRIE => 1,
|
||||
MAP => 1,
|
||||
SPARSE => 1,
|
||||
POOL => 1,
|
||||
TABLE => 2,
|
||||
RECORD => 1,
|
||||
|
||||
_ => 0,
|
||||
}
|
||||
}
|
39
src/util/macros.rs
Normal file
39
src/util/macros.rs
Normal file
@ -0,0 +1,39 @@
|
||||
#[macro_export]
|
||||
macro_rules! impl_szun {
|
||||
($type_name:ty) => {
|
||||
impl Into<Any> for $type_name { fn into(self) -> Any { to_any(self) } }
|
||||
impl TryFrom<Any> for $type_name { type Error = (); fn try_from(any: Any) -> Result<Self, Self::Error> { from_any(any) } }
|
||||
impl Clone for $type_name { fn clone(&self) -> Self { Self::from_ref(clone(self.to_ref(), None)) } }
|
||||
impl Drop for $type_name { fn drop(&mut self) { drop(self.to_ref()); } }
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_szun_generic {
|
||||
($type_name:ty) => {
|
||||
impl<T:Szun> Into<Any> for $type_name { fn into(self) -> Any { to_any(self) } }
|
||||
impl<T:Szun> TryFrom<Any> for $type_name { type Error = (); fn try_from(any: Any) -> Result<Self, Self::Error> { from_any(any) } }
|
||||
impl<T:Szun> Clone for $type_name { fn clone(&self) -> Self { Self::from_ref(clone(self.to_ref(), None)) } }
|
||||
impl<T:Szun> Drop for $type_name { fn drop(&mut self) { drop(self.to_ref()); } }
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_szun_sized {
|
||||
($type_name:ty) => {
|
||||
impl<const N:usize> Into<Any> for $type_name { fn into(self) -> Any { to_any(self) } }
|
||||
impl<const N:usize> TryFrom<Any> for $type_name { type Error = (); fn try_from(any: Any) -> Result<Self, Self::Error> { from_any(any) } }
|
||||
impl<const N:usize> Clone for $type_name { fn clone(&self) -> Self { Self::from_ref(clone(self.to_ref(), None)) } }
|
||||
impl<const N:usize> Drop for $type_name { fn drop(&mut self) { drop(self.to_ref()); } }
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_szun_generic_sized {
|
||||
($type_name:ty) => {
|
||||
impl<T:Szun, const N:usize> Into<Any> for $type_name { fn into(self) -> Any { to_any(self) } }
|
||||
impl<T:Szun, const N:usize> TryFrom<Any> for $type_name { type Error = (); fn try_from(any: Any) -> Result<Self, Self::Error> { from_any(any) } }
|
||||
impl<T:Szun, const N:usize> Clone for $type_name { fn clone(&self) -> Self { Self::from_ref(clone(self.to_ref(), None)) } }
|
||||
impl<T:Szun, const N:usize> Drop for $type_name { fn drop(&mut self) { drop(self.to_ref()); } }
|
||||
}
|
||||
}
|
1
src/util/mod.rs
Normal file
1
src/util/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod macros;
|
Loading…
x
Reference in New Issue
Block a user