From 346800370985a5cf5c8576309505f240d4233b9f Mon Sep 17 00:00:00 2001 From: Axel Nennker Date: Tue, 5 Jun 2018 15:26:29 +0200 Subject: [PATCH 1/7] tell which did already exists Signed-off-by: Axel Nennker --- libindy/src/commands/did.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libindy/src/commands/did.rs b/libindy/src/commands/did.rs index 7198e116a3..e7f0d923d8 100644 --- a/libindy/src/commands/did.rs +++ b/libindy/src/commands/did.rs @@ -216,7 +216,7 @@ impl DidCommandExecutor { if let Some(ref did) = my_did_info.did.as_ref() { if self.wallet_service.record_exists::(wallet_handle, did)? { - return Err(IndyError::DidError(DidError::AlreadyExistsError(format!("Did already exists")))); + return Err(IndyError::DidError(DidError::AlreadyExistsError(did.to_string()))); }; } From 2bbf62149692aea59ba3c2fc00da03e4b8b817e3 Mon Sep 17 00:00:00 2001 From: Axel Nennker Date: Mon, 18 Jun 2018 18:29:08 +0200 Subject: [PATCH 2/7] get rid of compiler warnings Signed-off-by: Axel Nennker --- libindy/src/commands/non_secrets.rs | 13 ++++++++----- libindy/src/services/wallet/encryption.rs | 3 +-- libindy/src/services/wallet/export_import.rs | 13 ++++++------- libindy/src/services/wallet/mod.rs | 10 ++++------ libindy/src/services/wallet/storage/default/mod.rs | 4 ---- libindy/src/services/wallet/storage/plugged/mod.rs | 3 +-- libindy/src/services/wallet/wallet.rs | 4 ---- .../utils/crypto/chacha20poly1305_ietf/sodium.rs | 7 ++----- 8 files changed, 22 insertions(+), 35 deletions(-) diff --git a/libindy/src/commands/non_secrets.rs b/libindy/src/commands/non_secrets.rs index 959b3b50a8..1f181aa550 100644 --- a/libindy/src/commands/non_secrets.rs +++ b/libindy/src/commands/non_secrets.rs @@ -199,10 +199,13 @@ impl NonSecretsCommandExecutor { self._check_type(type_)?; - let tag_names: Vec<&str> = match serde_json::from_str(tag_names_json) { - Ok(tag_names) => tag_names, - Err(serde_json_err) => return Err(IndyError::WalletError(WalletError::InputError(format!("Invalid tag names input: {}", tag_names_json)))) - }; + //let tag_names: Vec<&str> = match serde_json::from_str(tag_names_json) { + //Ok(tag_names) => tag_names, + //Err(serde_json_err) => return Err(IndyError::WalletError(WalletError::InputError(format!("Invalid tag names input: {}", tag_names_json)))) + //}; + let tag_names: Vec<&str> = serde_json::from_str(tag_names_json) + .map_err(|err| IndyError::WalletError(WalletError::InputError(format!("Cannot deserialize tag names: {}", err))))?; + let res = self.wallet_service.delete_record_tags(wallet_handle, type_, id, &tag_names)?; trace!("delete_record_tags <<< res: {:?}", res); @@ -330,4 +333,4 @@ pub struct SearchRecords { pub records: Option> } -impl JsonEncodable for SearchRecords {} \ No newline at end of file +impl JsonEncodable for SearchRecords {} diff --git a/libindy/src/services/wallet/encryption.rs b/libindy/src/services/wallet/encryption.rs index 8a4882a744..dabfb058fb 100644 --- a/libindy/src/services/wallet/encryption.rs +++ b/libindy/src/services/wallet/encryption.rs @@ -14,7 +14,6 @@ use services::wallet::WalletRecord; use super::wallet::Keys; use super::storage::{Tag, TagName, StorageEntity}; -use errors::common::CommonError; use errors::wallet::WalletError; pub(super) fn derive_key(input: &[u8], salt: &[u8; 32]) -> Result { @@ -182,4 +181,4 @@ mod tests { let u = decrypt_tags(&None, &tag_name_key, &tag_value_key).unwrap(); assert!(u.is_none()); } -} \ No newline at end of file +} diff --git a/libindy/src/services/wallet/export_import.rs b/libindy/src/services/wallet/export_import.rs index 31e4cda566..68e8b9e347 100644 --- a/libindy/src/services/wallet/export_import.rs +++ b/libindy/src/services/wallet/export_import.rs @@ -9,7 +9,7 @@ use utils::crypto::hash::Hash; use utils::crypto::chacha20poly1305_ietf::{ChaCha20Poly1305IETF, NONCE_LENGTH, ChaCha20Poly1305IETFNonce}; use utils::crypto::pwhash_argon2i13::PwhashArgon2i13; use utils::byte_array::_clone_into_array; -use services::wallet::encryption::{decrypt_merged, decrypt, encrypt_as_not_searchable, derive_key}; +use services::wallet::encryption::{decrypt, derive_key}; use errors::common::CommonError; @@ -373,11 +373,10 @@ mod tests { use serde_json; use ::utils::crypto::chacha20poly1305_ietf::{ChaCha20Poly1305IETF, ChaCha20Poly1305IETFKey}; use ::utils::environment::EnvironmentUtils; - use ::utils::test::TestUtils; use services::wallet::storage::WalletStorageType; use services::wallet::storage::default::SQLiteStorageType; use services::wallet::wallet::{Keys, Wallet}; - use services::wallet::encryption::{decrypt_merged, decrypt, encrypt_as_not_searchable}; + use services::wallet::encryption::{decrypt_merged}; use super::*; fn _wallet_path() -> std::path::PathBuf { @@ -423,7 +422,7 @@ mod tests { } fn _create_export_file() -> Box { - let mut path = EnvironmentUtils::tmp_file_path("export_directory"); + let path = EnvironmentUtils::tmp_file_path("export_directory"); if path.exists() { std::fs::remove_dir_all(path.clone()).unwrap(); } @@ -733,7 +732,7 @@ mod tests { tags.insert(format!("tag_name_{}_2", i), format!("tag_value_{}_2", i)); tags.insert(format!("~tag_name_{}_3", i), format!("tag_value_{}_3", i)); let tags_len = serde_json::to_string(&tags).unwrap().len(); - total_item_length += (4 + name.len() + value.len() + tags_len); + total_item_length += 4 + name.len() + value.len() + tags_len; wallet.add("type", &name, &value, &tags).unwrap(); } let total_unencrypted_length = total_item_length + item_count * 20; @@ -860,7 +859,7 @@ mod tests { tags.insert(format!("tag_name_{}_2", i), format!("tag_value_{}_2", i)); tags.insert(format!("~tag_name_{}_3", i), format!("tag_value_{}_3", i)); let tags_len = serde_json::to_string(&tags).unwrap().len(); - total_item_length += (4 + name.len() + value.len() + tags_len); + total_item_length += 4 + name.len() + value.len() + tags_len; wallet.add("type", &name, &value, &tags).unwrap(); } let total_unencrypted_length = total_item_length + item_count * 20; @@ -1110,4 +1109,4 @@ mod tests { let res = wallet.get(type1, name1, _options()); assert_match!(Err(WalletError::ItemNotFound), res); } -} \ No newline at end of file +} diff --git a/libindy/src/services/wallet/mod.rs b/libindy/src/services/wallet/mod.rs index c0ede5d398..00033d26b7 100644 --- a/libindy/src/services/wallet/mod.rs +++ b/libindy/src/services/wallet/mod.rs @@ -15,7 +15,6 @@ use std::fs; use std::fs::{OpenOptions, File, DirBuilder}; use std::io::{Read, Write}; use std::path::{Path, PathBuf}; -use std::mem; use named_type::NamedType; use std::rc::Rc; @@ -26,7 +25,7 @@ use errors::wallet::WalletError; use errors::common::CommonError; use utils::environment::EnvironmentUtils; use utils::sequence::SequenceUtils; -use utils::crypto::chacha20poly1305_ietf::{ChaCha20Poly1305IETF, ChaCha20Poly1305IETFKey}; +use utils::crypto::chacha20poly1305_ietf::{ChaCha20Poly1305IETFKey}; use self::export_import::{export, import}; use self::storage::{WalletStorage, WalletStorageType}; @@ -34,7 +33,6 @@ use self::storage::default::SQLiteStorageType; use self::storage::plugged::PluggedStorageType; use self::wallet::{Wallet, Keys}; use self::indy_crypto::utils::json::{JsonDecodable, JsonEncodable}; -use self::sodiumoxide::utils::memzero; use self::encryption::derive_key; use utils::crypto::pwhash_argon2i13::PwhashArgon2i13; @@ -577,7 +575,7 @@ impl WalletService { match self.open_wallet(name, None, credentials) { Err(err) => { // Ignores the error, since there is nothing that can be done - self.delete_wallet(name, credentials); + let _ = self.delete_wallet(name, credentials); Err(err) } Ok(wallet_handle) => { @@ -587,7 +585,7 @@ impl WalletService { match import(wallet, reader, &import_config.key) { Ok(_) => Ok(()), err @ Err(_) => { - self.delete_wallet(name, credentials); + let _ = self.delete_wallet(name, credentials); err } } @@ -1813,4 +1811,4 @@ mod tests { let res = wallet_service.open_wallet("test_wallet", None, &_credentials()); assert_match!(Err(_), res); } -} \ No newline at end of file +} diff --git a/libindy/src/services/wallet/storage/default/mod.rs b/libindy/src/services/wallet/storage/default/mod.rs index f0670af80b..166653ada1 100644 --- a/libindy/src/services/wallet/storage/default/mod.rs +++ b/libindy/src/services/wallet/storage/default/mod.rs @@ -12,12 +12,10 @@ use serde_json; use self::owning_ref::OwningHandle; use std::rc::Rc; -use utils::crypto::chacha20poly1305_ietf::ChaCha20Poly1305IETF; use utils::environment::EnvironmentUtils; use errors::wallet::WalletStorageError; use errors::common::CommonError; use services::wallet::language; -use sodiumoxide::utils::memzero; use super::{StorageIterator, WalletStorageType, WalletStorage, StorageEntity, EncryptedValue, Tag, TagName}; use super::super::{RecordOptions, SearchOptions}; @@ -735,8 +733,6 @@ mod tests { use super::super::Tag; use std::collections::HashMap; use std::env; - use ::utils::crypto::chacha20poly1305_ietf::ChaCha20Poly1305IETF; - fn _create_and_open_test_storage() -> Box { _prepare_path(); diff --git a/libindy/src/services/wallet/storage/plugged/mod.rs b/libindy/src/services/wallet/storage/plugged/mod.rs index c6e78b8492..b1b4f3a4d7 100644 --- a/libindy/src/services/wallet/storage/plugged/mod.rs +++ b/libindy/src/services/wallet/storage/plugged/mod.rs @@ -813,7 +813,6 @@ mod tests { use std::sync::RwLock; use self::rand::{thread_rng, Rng}; use std::clone::Clone; - use ::utils::crypto::chacha20poly1305_ietf::ChaCha20Poly1305IETF; impl PartialEq for StorageEntity { fn eq(&self, other: &StorageEntity) -> bool { @@ -2180,4 +2179,4 @@ mod tests { assert_eq!(&expected_free_record_call, debug.get(6).unwrap()); assert_eq!(&expected_free_search_call, debug.get(7).unwrap()); } -} \ No newline at end of file +} diff --git a/libindy/src/services/wallet/wallet.rs b/libindy/src/services/wallet/wallet.rs index acde6d951f..20aa2a211d 100644 --- a/libindy/src/services/wallet/wallet.rs +++ b/libindy/src/services/wallet/wallet.rs @@ -1,11 +1,8 @@ extern crate sodiumoxide; -use std; use std::collections::HashMap; -use std::io::{Write,Read}; use std::rc::Rc; -use serde_json; use utils::crypto::chacha20poly1305_ietf::{TAG_LENGTH, KEY_LENGTH, NONCE_LENGTH, ChaCha20Poly1305IETF,ChaCha20Poly1305IETFKey}; use utils::crypto::hmacsha256::{HMACSHA256, HMACSHA256Key}; @@ -13,7 +10,6 @@ use errors::wallet::WalletError; use errors::common::CommonError; use super::storage; -use super::storage::StorageEntity; use super::iterator::WalletIterator; use super::encryption::*; use super::query_encryption::encrypt_query; diff --git a/libindy/src/utils/crypto/chacha20poly1305_ietf/sodium.rs b/libindy/src/utils/crypto/chacha20poly1305_ietf/sodium.rs index 72289c9e71..5f62f9d202 100644 --- a/libindy/src/utils/crypto/chacha20poly1305_ietf/sodium.rs +++ b/libindy/src/utils/crypto/chacha20poly1305_ietf/sodium.rs @@ -1,12 +1,10 @@ extern crate sodiumoxide; use sodiumoxide::crypto::aead::chacha20poly1305_ietf; -use sodiumoxide::crypto::auth::hmacsha256; use errors::common::CommonError; use sodiumoxide::utils::increment_le; use utils::byte_array::_clone_into_array; -use utils::crypto::hmacsha256::{HMACSHA256, HMACSHA256Key}; pub const NONCE_LENGTH: usize = chacha20poly1305_ietf::NONCEBYTES; pub const KEY_LENGTH: usize = chacha20poly1305_ietf::KEYBYTES; @@ -55,7 +53,7 @@ impl ChaCha20Poly1305IETF { ChaCha20Poly1305IETFNonce { nonce: chacha20poly1305_ietf::Nonce(_clone_into_array(&bytes[..chacha20poly1305_ietf::NONCEBYTES])) } } - pub fn increment_nonce(mut nonce: &mut ChaCha20Poly1305IETFNonce) { + pub fn increment_nonce(nonce: &mut ChaCha20Poly1305IETFNonce) { increment_le(&mut nonce.nonce.0); } @@ -101,7 +99,6 @@ mod tests { fn encrypt_decrypt_works() { let data = randombytes::randombytes(100); let key = ChaCha20Poly1305IETF::generate_key(); - let hmac_key = HMACSHA256::generate_key(); let (c, nonce) = ChaCha20Poly1305IETF::generate_nonce_and_encrypt(&data, &key); let u = ChaCha20Poly1305IETF::decrypt(&c, &key, &nonce).unwrap(); @@ -117,4 +114,4 @@ mod tests { let u = ChaCha20Poly1305IETF::decrypt(&c, &key, &nonce).unwrap(); assert_eq!(data, u) } -} \ No newline at end of file +} From e73af8055a08a738dd72951c7d60b2a1a4c30da8 Mon Sep 17 00:00:00 2001 From: Axel Nennker Date: Fri, 22 Jun 2018 09:17:19 +0200 Subject: [PATCH 3/7] put the failing did into the error Signed-off-by: Axel Nennker --- libindy/src/commands/did.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libindy/src/commands/did.rs b/libindy/src/commands/did.rs index 6b37d5d1a6..c8bc197a3b 100644 --- a/libindy/src/commands/did.rs +++ b/libindy/src/commands/did.rs @@ -217,7 +217,7 @@ impl DidCommandExecutor { let (did, key) = self.crypto_service.create_my_did(&my_did_info)?; if self.wallet_service.record_exists::(wallet_handle, &did.did)? { - return Err(IndyError::DidError(DidError::AlreadyExistsError("Did already exists".to_string()))); + return Err(IndyError::DidError(DidError::AlreadyExistsError(did.to_string()))); }; self.wallet_service.add_indy_object(wallet_handle, &did.did, &did, &HashMap::new())?; From e0591731c3c8158d65998487b087f3e60b626785 Mon Sep 17 00:00:00 2001 From: Axel Nennker Date: Mon, 25 Jun 2018 14:24:52 +0200 Subject: [PATCH 4/7] restore TODO comment Signed-off-by: Axel Nennker --- libindy/src/services/wallet/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libindy/src/services/wallet/mod.rs b/libindy/src/services/wallet/mod.rs index 79573ecd21..d3eda90a52 100644 --- a/libindy/src/services/wallet/mod.rs +++ b/libindy/src/services/wallet/mod.rs @@ -583,7 +583,7 @@ impl WalletService { match self.open_wallet(name, None, credentials) { Err(err) => { // Ignores the error, since there is nothing that can be done - let _ = self.delete_wallet(name, credentials); + let _ = self.delete_wallet(name, credentials); // TODO: why do we ignore thr result here? ok is used to avoid warning Err(err) } Ok(wallet_handle) => { @@ -593,7 +593,7 @@ impl WalletService { match import(wallet, reader, &import_config.key) { Ok(_) => Ok(()), err @ Err(_) => { - let _ = self.delete_wallet(name, credentials); + let _ = self.delete_wallet(name, credentials); // TODO: why do we ignore thr result here? ok is used to avoid warning err } } From 358728c36cb9d350d0039dd2a3463ca65a783ccd Mon Sep 17 00:00:00 2001 From: Axel Nennker Date: Mon, 25 Jun 2018 16:08:38 +0200 Subject: [PATCH 5/7] fixed did error handling Signed-off-by: Axel Nennker --- libindy/src/commands/did.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libindy/src/commands/did.rs b/libindy/src/commands/did.rs index c8bc197a3b..6a431ba14c 100644 --- a/libindy/src/commands/did.rs +++ b/libindy/src/commands/did.rs @@ -217,7 +217,7 @@ impl DidCommandExecutor { let (did, key) = self.crypto_service.create_my_did(&my_did_info)?; if self.wallet_service.record_exists::(wallet_handle, &did.did)? { - return Err(IndyError::DidError(DidError::AlreadyExistsError(did.to_string()))); + return Err(IndyError::DidError(DidError::AlreadyExistsError(did.did))); }; self.wallet_service.add_indy_object(wallet_handle, &did.did, &did, &HashMap::new())?; From 9c8762b09716c8da550fd3dd5cd6e03f7de2ff54 Mon Sep 17 00:00:00 2001 From: Sergey Minaev Date: Tue, 26 Jun 2018 17:48:47 +0300 Subject: [PATCH 6/7] Restore CLI testing on Amazon linux. Signed-off-by: Sergey Minaev --- Jenkinsfile.cd | 26 ++++++++++++-------------- Jenkinsfile.ci | 6 +----- cli/src/commands/common.rs | 13 ++++++++++++- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/Jenkinsfile.cd b/Jenkinsfile.cd index 20cadecea4..433c0616de 100644 --- a/Jenkinsfile.cd +++ b/Jenkinsfile.cd @@ -230,23 +230,21 @@ def linuxTesting(file, env_name, network_name, stashBuildResults) { } } - if (env_name == 'Ubuntu') { // TODO: Delete condition IS-702 - sh "cp libnullpay/target/release/libnullpay.so cli" - sh "cp libindy/target/release/libindy.so cli" - dir('cli') { - testEnv.inside("--ip=\"10.0.0.3\" --network=${network_name}") { - echo "${env_name} Indy Cli Test: Build" - sh "LIBRARY_PATH=./ RUST_BACKTRACE=1 cargo build --release" + sh "cp libnullpay/target/release/libnullpay.so cli" + sh "cp libindy/target/release/libindy.so cli" + dir('cli') { + testEnv.inside("--ip=\"10.0.0.3\" --network=${network_name}") { + echo "${env_name} Indy Cli Test: Build" + sh "LIBRARY_PATH=./ RUST_BACKTRACE=1 cargo build --release" - echo "${env_name} Indy Cli Test: Build Tests" - sh 'LIBRARY_PATH=./ RUST_BACKTRACE=1 cargo test --release --features "nullpay_plugin" --no-run' + echo "${env_name} Indy Cli Test: Build Tests" + sh 'LIBRARY_PATH=./ RUST_BACKTRACE=1 cargo test --release --features "nullpay_plugin" --no-run' - echo "${env_name} Indy Cli Test: Run tests" - sh 'LD_LIBRARY_PATH=./:${LD_LIBRARY_PATH} RUST_BACKTRACE=1 RUST_LOG=indy::=debug,zmq=trace RUST_TEST_THREADS=1 TEST_POOL_IP=10.0.0.2 cargo test --release --features "nullpay_plugin"' + echo "${env_name} Indy Cli Test: Run tests" + sh 'LD_LIBRARY_PATH=./:${LD_LIBRARY_PATH} RUST_BACKTRACE=1 RUST_LOG=indy::=debug,zmq=trace RUST_TEST_THREADS=1 TEST_POOL_IP=10.0.0.2 cargo test --release --features "nullpay_plugin"' - if (stashBuildResults) { - stash includes: 'target/release/indy-cli', name: 'IndyCliUbuntuBuildResult' - } + if (stashBuildResults) { + stash includes: 'target/release/indy-cli', name: 'IndyCliUbuntuBuildResult' } } } diff --git a/Jenkinsfile.ci b/Jenkinsfile.ci index 1522446276..0322ce59ef 100644 --- a/Jenkinsfile.ci +++ b/Jenkinsfile.ci @@ -362,10 +362,6 @@ def linuxNodejsTesting(env_name, network_name, testEnv) { } def linuxCLITesting(env_name, network_name, testEnv) { - if (env_name == "RedHat"){ // TODO: Delete it IS-702 - return; - } - unstash name: "LibindyCliSO${env_name}" unstash name: "LibnullpayCliSO${env_name}" @@ -457,4 +453,4 @@ def setupBrewPackages() { sh "brew switch libsodium 1.0.12" sh "brew switch openssl 1.0.2l" sh "brew switch zeromq 4.2.3" -} \ No newline at end of file +} diff --git a/cli/src/commands/common.rs b/cli/src/commands/common.rs index 2a176bf334..0a0faddb4f 100644 --- a/cli/src/commands/common.rs +++ b/cli/src/commands/common.rs @@ -202,11 +202,22 @@ pub mod tests { } pub fn load_null_payment_plugin(ctx: &CommandContext) -> () { - let lib = libloading::Library::new(NULL_PAYMENT_PLUGIN).unwrap(); + let lib = _load_lib(NULL_PAYMENT_PLUGIN).unwrap(); unsafe { let init_func: libloading::Symbol ErrorCode> = lib.get(NULL_PAYMENT_PLUGIN_INIT_FUNCTION.as_bytes()).unwrap(); init_func(); } ctx.add_plugin(NULL_PAYMENT_PLUGIN, lib) } + + #[cfg(unix)] + fn _load_lib(library: &str) -> libloading::Result { + libloading::os::unix::Library::open(Some(library), ::libc::RTLD_NOW | ::libc::RTLD_NODELETE) + .map(libloading::Library::from) + } + + #[cfg(not(unix))] + fn _load_lib(library: &str) -> libloading::Result { + libloading::Library::new(library) + } } \ No newline at end of file From 72a766b37f9693ae24ccc89f3d6f5b14e8d80ecd Mon Sep 17 00:00:00 2001 From: Sergey Minaev Date: Wed, 27 Jun 2018 11:00:52 +0300 Subject: [PATCH 7/7] Fix one more test for plugin loading verification. Signed-off-by: Sergey Minaev --- cli/src/commands/common.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/cli/src/commands/common.rs b/cli/src/commands/common.rs index 0a0faddb4f..6fa97d1ad4 100644 --- a/cli/src/commands/common.rs +++ b/cli/src/commands/common.rs @@ -112,7 +112,7 @@ pub mod load_plugin_command { } pub fn load_plugin(ctx: &CommandContext, library: &str, initializer: &str) -> Result<(), ()> { - let lib = libloading::Library::new(library) + let lib = _load_lib(library) .map_err(|_| println_err!("Plugin not found: {:?}", library))?; unsafe { @@ -131,6 +131,17 @@ pub fn load_plugin(ctx: &CommandContext, library: &str, initializer: &str) -> Re Ok(()) } +#[cfg(all(unix, test))] +fn _load_lib(library: &str) -> libloading::Result { + libloading::os::unix::Library::open(Some(library), ::libc::RTLD_NOW | ::libc::RTLD_NODELETE) + .map(libloading::Library::from) +} + +#[cfg(any(not(unix), not(test)))] +fn _load_lib(library: &str) -> libloading::Result { + libloading::Library::new(library) +} + pub mod exit_command { use super::*; @@ -209,15 +220,4 @@ pub mod tests { } ctx.add_plugin(NULL_PAYMENT_PLUGIN, lib) } - - #[cfg(unix)] - fn _load_lib(library: &str) -> libloading::Result { - libloading::os::unix::Library::open(Some(library), ::libc::RTLD_NOW | ::libc::RTLD_NODELETE) - .map(libloading::Library::from) - } - - #[cfg(not(unix))] - fn _load_lib(library: &str) -> libloading::Result { - libloading::Library::new(library) - } } \ No newline at end of file