Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft: Start implementing generic wrapper types #666

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions rustler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ mod alloc;
pub mod types;

mod term;
mod wrapped_types;

pub use crate::term::Term;
pub use crate::types::{
Atom, Binary, Decoder, Encoder, ErlOption, ListIterator, LocalPid, MapIterator, NewBinary,
OwnedBinary, Reference,
Atom, Binary, Decoder, Encoder, ErlOption, LocalPid, NewBinary, OwnedBinary,
};

pub use crate::wrapped_types::{ListIterator, Map, MapIterator, Reference, Tuple, Wrapper};

#[cfg(feature = "big_integer")]
pub use crate::types::BigInt;

Expand Down
5 changes: 1 addition & 4 deletions rustler/src/serde/de.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use crate::serde::{atoms, error::Error, util};
use crate::{
types::{ListIterator, MapIterator},
Term, TermType,
};
use crate::{ListIterator, MapIterator, Term, TermType};
use serde::{
de::{
self, Deserialize, DeserializeSeed, EnumAccess, MapAccess, SeqAccess, VariantAccess,
Expand Down
10 changes: 7 additions & 3 deletions rustler/src/serde/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::io::Write;

use crate::serde::{atoms, error::Error, util};
use crate::wrapper::list::make_list;
use crate::{types::tuple, Encoder, Env, OwnedBinary, Term};
use crate::{Encoder, Env, OwnedBinary, Term};
use serde::ser::{self, Serialize};

#[inline]
Expand Down Expand Up @@ -336,7 +336,7 @@ impl<'a> SequenceSerializer<'a> {

#[inline]
fn to_tuple(&self) -> Result<Term<'a>, Error> {
Ok(tuple::make_tuple(self.ser.env, &self.items))
Ok(self.ser.env.make_tuple(&self.items).into())
}
}

Expand Down Expand Up @@ -460,7 +460,11 @@ impl<'a> MapSerializer<'a> {

#[inline]
fn to_map(&self) -> Result<Term<'a>, Error> {
Term::map_from_arrays(self.ser.env, &self.keys, &self.values).or(Err(Error::InvalidMap))
self.ser
.env
.map_from_arrays(&self.keys, &self.values)
.map(|map| map.into())
.or(Err(Error::InvalidMap))
}

#[inline]
Expand Down
7 changes: 5 additions & 2 deletions rustler/src/serde/util.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::serde::{atoms, Error};
use crate::{types::tuple, Binary, Decoder, Encoder, Env, Term};
use crate::{Binary, Decoder, Encoder, Env, Term, Tuple};

/// Converts an `&str` to either an existing atom or an Elixir bitstring.
pub fn str_to_term<'a>(env: &Env<'a>, string: &str) -> Result<Term<'a>, Error> {
Expand Down Expand Up @@ -62,7 +62,10 @@ pub fn validate_tuple(term: Term, len: Option<usize>) -> Result<Vec<Term>, Error
return Err(Error::ExpectedTuple);
}

let tuple = tuple::get_tuple(term).or(Err(Error::ExpectedTuple))?;
let tuple = Tuple::try_from(term)
.or(Err(Error::ExpectedTuple))?
.to_vec();

match len {
None => Ok(tuple),
Some(len) => {
Expand Down
13 changes: 13 additions & 0 deletions rustler/src/types/atom.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::wrapper::atom;
use crate::wrapper::NIF_TERM;
use crate::Wrapper;
use crate::{Decoder, Encoder, Env, Error, NifResult, Term};

// Atoms are a special case of a term. They can be stored and used on all envs regardless of where
Expand Down Expand Up @@ -81,6 +82,18 @@ impl Atom {
}
}

impl<'a> Wrapper<'a> for Atom {
const WRAPPED_TYPE: crate::TermType = crate::TermType::Atom;

fn unwrap(&self) -> Term<'a> {
unimplemented!()
}

unsafe fn wrap_unchecked(term: Term<'a>) -> Self {
Atom::from_nif_term(term.as_c_arg())
}
}

use std::fmt;
impl fmt::Debug for Atom {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
Expand Down
14 changes: 8 additions & 6 deletions rustler/src/types/elixir_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@
//! `#[module = "Elixir.TheStructModule"]`.

use super::atom::{self, Atom};
use super::map::map_new;
use crate::{Env, NifResult, Term};
use crate::{Env, Error, Map, NifResult, Term};

pub fn get_ex_struct_name(map: Term) -> NifResult<Atom> {
// In an Elixir struct the value in the __struct__ field is always an atom.
map.map_get(atom::__struct__()).and_then(Atom::from_term)
let map: Map<'_> = map.try_into()?;
map.get(atom::__struct__())
.ok_or(Error::BadArg)
.and_then(Atom::from_term)
}

pub fn make_ex_struct<'a>(env: Env<'a>, struct_module: &str) -> NifResult<Term<'a>> {
let map = map_new(env);
pub fn make_ex_struct<'a>(env: Env<'a>, struct_module: &str) -> NifResult<Map<'a>> {
let map = env.new_map();

let struct_atom = atom::__struct__();
let module_atom = Atom::from_str(env, struct_module)?;

map.map_put(struct_atom, module_atom)
map.put(struct_atom, module_atom)
}
204 changes: 0 additions & 204 deletions rustler/src/types/list.rs

This file was deleted.

14 changes: 1 addition & 13 deletions rustler/src/types/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::wrapped_types::MapIterator;
use crate::{Env, Error, NifResult, Term};

#[macro_use]
Expand All @@ -12,28 +13,15 @@ pub mod big_int;
#[cfg(feature = "big_integer")]
pub use num_bigint::BigInt;

#[doc(hidden)]
pub mod list;
pub use crate::types::list::ListIterator;

#[doc(hidden)]
pub mod map;
pub use self::map::MapIterator;

#[doc(hidden)]
pub mod primitive;
#[doc(hidden)]
pub mod string;
pub mod tuple;

#[doc(hidden)]
pub mod local_pid;
pub use self::local_pid::LocalPid;

#[doc(hidden)]
pub mod reference;
pub use self::reference::Reference;

pub mod i128;
pub mod path;

Expand Down
Loading
Loading