Skip to content

Commit 5dedc35

Browse files
committed
Initial commit
1 parent 6cfb13e commit 5dedc35

File tree

14 files changed

+2172
-0
lines changed

14 files changed

+2172
-0
lines changed

.gitignore

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Generated by Cargo
2+
# will have compiled files and executables
3+
/target/
4+
5+
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
6+
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
7+
Cargo.lock
8+
9+
# These are backup files generated by rustfmt
10+
**/*.rs.bk
11+
12+
# Editor
13+
**/.vscode/

Cargo.toml

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[package]
2+
name = "symengine"
3+
version = "0.1.0"
4+
authors = ["h <[email protected]>"]
5+
edition = "2018"
6+
7+
description = "Unofficial Rust wrappers to the C++ library SymEngine, a fast C++ symbolic manipulation library."
8+
homepage = "https://github.com/podo-os"
9+
repository = "https://github.com/podo-os/symengine.rs"
10+
readme = "README.md"
11+
license = "BSD-3-Clause"
12+
13+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
14+
15+
[features]
16+
default = ["serde"]
17+
18+
[dependencies]
19+
serde = { version = "1.0", optional = true }
20+
symengine-sys = { path = "sys" }
21+
22+
[dev-dependencies]
23+
serde_json = "1.0"
24+
25+
[workspace]
26+
members = [
27+
"sys",
28+
]

LICENSE

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Copyright (c) 2020, Ho Kim
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions are met:
6+
7+
1. Redistributions of source code must retain the above copyright notice, this
8+
list of conditions and the following disclaimer.
9+
10+
2. Redistributions in binary form must reproduce the above copyright notice,
11+
this list of conditions and the following disclaimer in the documentation
12+
and/or other materials provided with the distribution.
13+
14+
3. Neither the name of the author nor the names of its contributors may be used
15+
to endorse or promote products derived from this software without specific
16+
prior written permission.
17+
18+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

src/expr.rs

+220
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
use std::cell::UnsafeCell;
2+
use std::ffi::{CStr, CString};
3+
use std::fmt;
4+
5+
use symengine_sys::*;
6+
7+
#[cfg(feature = "serde")]
8+
use serde::{Deserialize, Deserializer, Serialize, Serializer};
9+
10+
pub struct Expression {
11+
pub(crate) basic: UnsafeCell<basic_struct>,
12+
}
13+
14+
impl Expression {
15+
pub fn new<T>(expr: T) -> Self
16+
where
17+
T: Into<Vec<u8>> + fmt::Display,
18+
{
19+
let expr = CString::new(expr).unwrap();
20+
21+
let new = Self::default();
22+
unsafe {
23+
basic_parse(new.basic.get(), expr.as_ptr());
24+
}
25+
new
26+
}
27+
28+
fn from_value<T>(
29+
f: unsafe extern "C" fn(*mut basic_struct, T) -> CWRAPPER_OUTPUT_TYPE,
30+
value: T,
31+
) -> Self {
32+
let expr = Self::default();
33+
unsafe {
34+
f(expr.basic.get(), value);
35+
}
36+
expr
37+
}
38+
}
39+
40+
impl Default for Expression {
41+
fn default() -> Self {
42+
unsafe {
43+
let mut basic = std::mem::MaybeUninit::uninit().assume_init();
44+
basic_new_stack(&mut basic);
45+
46+
Self {
47+
basic: UnsafeCell::new(basic),
48+
}
49+
}
50+
}
51+
}
52+
53+
impl From<i64> for Expression {
54+
fn from(value: i64) -> Self {
55+
Self::from_value(integer_set_si, value)
56+
}
57+
}
58+
59+
impl From<u64> for Expression {
60+
fn from(value: u64) -> Self {
61+
Self::from_value(integer_set_ui, value)
62+
}
63+
}
64+
65+
impl From<f64> for Expression {
66+
fn from(value: f64) -> Self {
67+
Self::from_value(real_double_set_d, value)
68+
}
69+
}
70+
71+
impl Clone for Expression {
72+
fn clone(&self) -> Self {
73+
let new = Expression::default();
74+
unsafe { basic_assign(new.basic.get(), self.basic.get()) };
75+
new
76+
}
77+
}
78+
79+
impl Drop for Expression {
80+
fn drop(&mut self) {
81+
unsafe {
82+
basic_free_stack(self.basic.get());
83+
}
84+
}
85+
}
86+
87+
impl fmt::Debug for Expression {
88+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89+
fmt::Debug::fmt(self.as_str(), f)
90+
}
91+
}
92+
93+
impl Expression {
94+
pub fn as_str(&self) -> &str {
95+
let expr = unsafe { CStr::from_ptr(basic_str(self.basic.get())) };
96+
expr.to_str().unwrap()
97+
}
98+
99+
fn binary_op(
100+
self,
101+
rhs: Self,
102+
op: unsafe extern "C" fn(
103+
*mut basic_struct,
104+
*mut basic_struct,
105+
*mut basic_struct,
106+
) -> CWRAPPER_OUTPUT_TYPE,
107+
) -> Self {
108+
let out = Self::default();
109+
unsafe {
110+
op(out.basic.get(), self.basic.get(), rhs.basic.get());
111+
}
112+
out
113+
}
114+
115+
fn cmp_eq_op(
116+
&self,
117+
rhs: &Self,
118+
op: unsafe extern "C" fn(*mut basic_struct, *mut basic_struct) -> i32,
119+
) -> bool {
120+
unsafe { op(self.basic.get(), rhs.basic.get()) == 1 }
121+
}
122+
}
123+
124+
impl<T> std::ops::Add<T> for Expression
125+
where
126+
T: Atomic,
127+
{
128+
type Output = Self;
129+
130+
fn add(self, rhs: T) -> Self {
131+
self.binary_op(rhs.into(), basic_add)
132+
}
133+
}
134+
135+
impl<T> std::ops::Sub<T> for Expression
136+
where
137+
T: Atomic,
138+
{
139+
type Output = Self;
140+
141+
fn sub(self, rhs: T) -> Self {
142+
self.binary_op(rhs.into(), basic_sub)
143+
}
144+
}
145+
146+
impl<T> std::ops::Mul<T> for Expression
147+
where
148+
T: Atomic,
149+
{
150+
type Output = Self;
151+
152+
fn mul(self, rhs: T) -> Self {
153+
self.binary_op(rhs.into(), basic_mul)
154+
}
155+
}
156+
157+
impl<T> std::ops::Div<T> for Expression
158+
where
159+
T: Atomic,
160+
{
161+
type Output = Self;
162+
163+
fn div(self, rhs: T) -> Self {
164+
self.binary_op(rhs.into(), basic_div)
165+
}
166+
}
167+
168+
impl<T> PartialEq<T> for Expression
169+
where
170+
T: Clone + Symbol,
171+
{
172+
fn eq(&self, other: &T) -> bool {
173+
self.eq(&other.clone().into())
174+
}
175+
}
176+
177+
impl PartialEq for Expression {
178+
fn eq(&self, other: &Self) -> bool {
179+
let lhs = Expression::default();
180+
let rhs = Expression::default();
181+
182+
unsafe {
183+
basic_expand(lhs.basic.get(), self.basic.get());
184+
basic_expand(rhs.basic.get(), other.basic.get());
185+
}
186+
lhs.cmp_eq_op(&rhs, basic_eq)
187+
}
188+
}
189+
190+
#[cfg(feature = "serde")]
191+
impl Serialize for Expression {
192+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
193+
where
194+
S: Serializer,
195+
{
196+
serializer.serialize_str(self.as_str())
197+
}
198+
}
199+
200+
#[cfg(feature = "serde")]
201+
impl<'de> Deserialize<'de> for Expression {
202+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
203+
where
204+
D: Deserializer<'de>,
205+
{
206+
let expr = <&str>::deserialize(deserializer)?;
207+
Ok(Self::new(expr))
208+
}
209+
}
210+
211+
pub trait Atomic: Into<Expression> {}
212+
213+
impl<T: Symbol> Atomic for T {}
214+
impl Atomic for Expression {}
215+
216+
pub trait Symbol: Into<Expression> {}
217+
218+
impl Symbol for i64 {}
219+
impl Symbol for u64 {}
220+
impl Symbol for f64 {}

src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
mod expr;
2+
mod map;
3+
4+
pub use self::expr::Expression;
5+
pub use self::map::ExpressionMap;

0 commit comments

Comments
 (0)