mirror of
https://github.com/CoolProp/CoolProp.git
synced 2026-01-09 14:08:08 -05:00
Add Rust Wrapper (#1977)
* Add Rust Wrapper Signed-off-by: Steffen Golle <somnium@stampernet.de> * Remove Rust Wrapper Signed-off-by: Steffen Golle <somnium@stampernet.de> * Add Rust Wrapper as submodule Signed-off-by: Steffen Golle <somnium@stampernet.de> * Add Rust Wrapper as submodule Signed-off-by: Steffen Golle <somnium@stampernet.de> * Remove Rust wrapper submodule * Readd Rust wrapper version 0.2.0
This commit is contained in:
3
wrappers/Rust/.gitignore
vendored
Normal file
3
wrappers/Rust/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/target
|
||||
Cargo.lock
|
||||
/.vscode
|
||||
22
wrappers/Rust/Cargo.toml
Normal file
22
wrappers/Rust/Cargo.toml
Normal file
@@ -0,0 +1,22 @@
|
||||
[package]
|
||||
name = "coolprop-rs"
|
||||
version = "0.2.0"
|
||||
authors = ["Steffen Golle <somnium@stampernet.de>"]
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/sgolle/coolprop-rs"
|
||||
documentation = "https://github.com/sgolle/coolprop-rs"
|
||||
homepage = "https://crates.io/crates/coolprop-rs"
|
||||
description = """
|
||||
Coolprop Wrapper for Rust
|
||||
"""
|
||||
keywords = ["coolprop", "wrapper"]
|
||||
categories = ["api-bindings", "external-ffi-bindings"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.55"
|
||||
21
wrappers/Rust/LICENSE
Normal file
21
wrappers/Rust/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Steffen Golle
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
51
wrappers/Rust/README.md
Normal file
51
wrappers/Rust/README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Welcome to coolprop-rs
|
||||
|
||||
**EXPERIMENTAL** CoolProp Wrapper for Rust
|
||||
|
||||
The wrapper uses rust-bindgen to create the bindings to the C++ shared library of CoolProp and adds some wrapper functions. The wrapper should work on all platforms that CoolProp and Rust work on.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
The CoolProp shared library (_libCoolProp.so_) and header file (_CoolPropLib.h_) must be installed on the computer in the systems folder. On Linux e. g. _/usr/lib64_ and _/usr/include_. Instructions to compile and install CoolProp for your system can be found on the project page of [CoolProp](https://github.com/CoolProp/CoolProp).
|
||||
|
||||
## Installation
|
||||
|
||||
The wrapper gets published on [crates.io](https://crates.io/crates/coolprop-rs) as `coolplot-rs` and you can add the library in your project.
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
coolprop-rs = "0.2"
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
At the moment the wrapper provides access to either the full C++ bindings directly or a small subset of methods which utilizes Rust types, error handling and unit testing.
|
||||
|
||||
The C++ bindings can be used with:
|
||||
|
||||
Rust:
|
||||
|
||||
```Rust
|
||||
use coolprop-rs::bindings::*;
|
||||
```
|
||||
|
||||
The subset of Rust methods are at the moment **PropsSI()** and **HAPropsSI()**:
|
||||
|
||||
Rust:
|
||||
|
||||
```Rust
|
||||
use coolprop-rs;
|
||||
println!("{:?}", coolprop-rs::PropsSI("H", "T", 300.0, "Q", 1.0, "R134a").unwrap());
|
||||
println!("{:?}", coolprop-rs::HAPropsSI("H", "T", 300.0, "P", 100000.0, "R", 0.0).unwrap());
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```bash
|
||||
413265.6843372975
|
||||
27013.112479771713
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This Rust package is released under the terms of the MIT license.
|
||||
34
wrappers/Rust/build.rs
Normal file
34
wrappers/Rust/build.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
extern crate bindgen;
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
// Tell cargo to tell rustc to link the system bzip2
|
||||
// shared library.
|
||||
println!("cargo:rustc-link-lib=CoolProp");
|
||||
|
||||
// Tell cargo to invalidate the built crate whenever the wrapper changes
|
||||
println!("cargo:rerun-if-changed=wrapper.h");
|
||||
|
||||
// The bindgen::Builder is the main entry point
|
||||
// to bindgen, and lets you build up options for
|
||||
// the resulting bindings.
|
||||
let bindings = bindgen::Builder::default()
|
||||
// The input header we would like to generate
|
||||
// bindings for.
|
||||
.header("wrapper.h")
|
||||
// Tell cargo to invalidate the built crate whenever any of the
|
||||
// included header files changed.
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
|
||||
// Finish the builder and generate the bindings.
|
||||
.generate()
|
||||
// Unwrap the Result and panic on failure.
|
||||
.expect("Unable to generate bindings");
|
||||
|
||||
// Write the bindings to the $OUT_DIR/bindings.rs file.
|
||||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
bindings
|
||||
.write_to_file(out_path.join("bindings.rs"))
|
||||
.expect("Couldn't write bindings!");
|
||||
}
|
||||
6
wrappers/Rust/src/bindings.rs
Normal file
6
wrappers/Rust/src/bindings.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
122
wrappers/Rust/src/lib.rs
Normal file
122
wrappers/Rust/src/lib.rs
Normal file
@@ -0,0 +1,122 @@
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::panic;
|
||||
|
||||
pub mod bindings;
|
||||
|
||||
// macro_rules! c_str {
|
||||
// ($s:expr) => {{
|
||||
// concat!($s, "\0").as_ptr() as *const i8
|
||||
// }};
|
||||
// }
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CoolPropError;
|
||||
|
||||
impl error::Error for CoolPropError {
|
||||
// fn description(&self) -> &str {
|
||||
// // Both underlying errors already impl `Error`, so we defer to their
|
||||
// // implementations.
|
||||
// match *self {
|
||||
// // Normally we can just write `err.description()`, but the error
|
||||
// // type has a concrete method called `description`, which conflicts
|
||||
// // with the trait method. For now, we must explicitly call
|
||||
// // `description` through the `Error` trait.
|
||||
// CoolPropError::Parse(ref err) => error::Error::description(err),
|
||||
// }
|
||||
// }
|
||||
|
||||
// fn cause(&self) -> Option<&error::Error> {
|
||||
// match *self {
|
||||
// // N.B. Both of these implicitly cast `err` from their concrete
|
||||
// // types (either `&io::Error` or `&num::ParseIntError`)
|
||||
// // to a trait object `&Error`. This works because both error types
|
||||
// // implement `Error`.
|
||||
// CoolPropError::Parse(ref err) => Some(err),
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
impl fmt::Display for CoolPropError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
// Underlying errors already impl `Display`, so we defer to
|
||||
// their implementations.
|
||||
CoolPropError => write!(f, "CoolProp error: {}", CoolPropError),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn PropsSI(
|
||||
output: &str,
|
||||
name1: &str,
|
||||
prop1: f64,
|
||||
name2: &str,
|
||||
prop2: f64,
|
||||
refr: &str,
|
||||
) -> Result<f64, CoolPropError> {
|
||||
let result = panic::catch_unwind(|| unsafe {
|
||||
bindings::PropsSI(
|
||||
format!("{}{}", output, "\0").as_ptr() as *const i8,
|
||||
format!("{}{}", name1, "\0").as_ptr() as *const i8,
|
||||
prop1,
|
||||
format!("{}{}", name2, "\0").as_ptr() as *const i8,
|
||||
prop2,
|
||||
format!("{}{}", refr, "\0").as_ptr() as *const i8,
|
||||
)
|
||||
});
|
||||
match result {
|
||||
Ok(result) => Ok(result),
|
||||
Err(_) => Err(CoolPropError),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn HAPropsSI(
|
||||
output: &str,
|
||||
name1: &str,
|
||||
prop1: f64,
|
||||
name2: &str,
|
||||
prop2: f64,
|
||||
name3: &str,
|
||||
prop3: f64,
|
||||
) -> Result<f64, CoolPropError> {
|
||||
let result = panic::catch_unwind(|| unsafe {
|
||||
bindings::HAPropsSI(
|
||||
format!("{}{}", output, "\0").as_ptr() as *const i8,
|
||||
format!("{}{}", name1, "\0").as_ptr() as *const i8,
|
||||
prop1,
|
||||
format!("{}{}", name2, "\0").as_ptr() as *const i8,
|
||||
prop2,
|
||||
format!("{}{}", name3, "\0").as_ptr() as *const i8,
|
||||
prop3,
|
||||
)
|
||||
});
|
||||
match result {
|
||||
Ok(result) => Ok(result),
|
||||
Err(_) => Err(CoolPropError),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_high_level_interface() {
|
||||
assert_eq!(
|
||||
PropsSI("H", "T", 300.0, "Q", 1.0, "R134a").unwrap(),
|
||||
413265.6843372975
|
||||
);
|
||||
assert_eq!(
|
||||
HAPropsSI("H", "T", 300.0, "P", 100000.0, "R", 0.0).unwrap(),
|
||||
27013.112479771713
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn test_low_level_interface() {
|
||||
// let mut state = bindings::AbstractState("HEOS", "Water")
|
||||
// }
|
||||
}
|
||||
2
wrappers/Rust/wrapper.h
Normal file
2
wrappers/Rust/wrapper.h
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "stdbool.h"
|
||||
#include "CoolPropLib.h"
|
||||
Reference in New Issue
Block a user