This repository has been archived on 2025-03-27. You can view files and clone it, but cannot push or open issues or pull requests.
szun-old/src/interface/record.rs

138 lines
3.3 KiB
Rust

use crate::runtime::{
util::{name_indexof, name_keyof},
Reference,
acquire, release,
schema_has,
type_key,
record_length,
record_at, record_update,
record_indexof, record_keyof,
record_type,
};
use crate::tag;
use super::record;
pub struct Record {
managed:bool,
addr:Reference,
}
impl Record {
pub fn new(schema:usize) -> Result<Self,()>
{
if unsafe {schema_has(schema)} {
Ok(Self {
managed:true,
addr:unsafe {acquire(record(schema))},
})
} else {
Err(())
}
}
pub fn with(schema:usize, data:Vec<(&str, Reference)>) -> Result<Self,()>
{
match Self::new(schema) {
Ok(mut obj) => {
for (key, value) in data {
obj.set(key, value);
}
Ok(obj)
}
Err(_) => Err(())
}
}
pub fn with_values(schema:usize, data:Vec<Reference>) -> Result<Self,()>
{
match Self::new(schema) {
Ok(mut obj) => {
for index in 0..data.len() {
obj.set_at(index, data[index]);
}
Ok(obj)
}
Err(_) => Err(())
}
}
pub fn length(&self) -> usize
{
unsafe {record_length(self.addr)}
}
pub fn set_at(&mut self, index:usize, source:Reference)
{
unsafe { record_update(self.addr, index, source); }
}
pub fn set(&mut self, key:&str, source:Reference)
{
match self.indexof(key) {
Some(index) => {
unsafe { record_update(self.addr, index, source); }
}
None => { }
}
}
pub fn at(&self, index:usize) -> Reference
{
unsafe {record_at(self.addr, index)}
}
pub fn get(&self, key:&str) -> Reference
{
match self.indexof(key) {
Some(index) => {
unsafe {record_at(self.addr, index)}
}
None => Reference::null()
}
}
pub fn indexof(&self, key:&str) -> Option<usize>
{
let key_index = name_indexof(key);
let result = unsafe {record_indexof(self.addr, key_index)};
if result != self.length() {
Some(result)
} else {
None
}
}
pub fn keyof(&self, index:usize) -> Option<String>
{
let result = unsafe {record_keyof(self.addr, index)};
if result != 0 {
Some(name_keyof(result))
}
else {
None
}
}
pub fn kindof(&self, index:usize) -> usize
{
unsafe {record_type(self.addr, index)}
}
}
impl TryFrom<Reference> for Record {
type Error = ();
fn try_from(addr:Reference) -> Result<Self, Self::Error> {
return if(unsafe {type_key(addr.class)} == tag::RECORD) {
Ok(Self { managed:false, addr:addr })
}
else {
Err(())
}
}
}
impl std::ops::Deref for Record {
type Target = Reference;
fn deref(&self) -> &Self::Target { return &self.addr; }
}
impl Drop for Record {
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
}