#![doc = include_str!("../README.md")]
pub use account_id::{parse_account, parse_h160_account};
#[cfg(feature = "integration-tests")]
#[allow(deprecated)]
use assert_cmd::cargo::cargo_bin;
pub use build::Profile;
pub use docker::Docker;
pub use errors::Error;
pub use git::{Git, GitHub, Release};
pub use helpers::{
find_contract_artifact_path, find_workspace_root, get_project_name_from_path,
get_relative_or_absolute_path, is_root, replace_in_file,
};
pub use metadata::format_type;
pub use signer::create_signer;
pub use sourcing::set_executable_permission;
use std::{cmp::Ordering, net::TcpListener, ops::Deref};
#[cfg(feature = "integration-tests")]
use std::{ffi::OsStr, path::Path};
pub use subxt::{Config, PolkadotConfig as DefaultConfig};
pub use subxt_signer::sr25519::Keypair;
pub use templates::{
extractor::extract_template_files,
frontend::{FrontendTemplate, FrontendType},
};
pub use test::test_project;
pub mod account_id;
pub(crate) mod api;
pub mod build;
#[cfg(test)]
pub mod command_mock;
pub mod docker;
pub mod errors;
pub mod git;
pub mod helpers;
pub mod manifest;
pub mod metadata;
pub mod polkadot_sdk;
pub mod signer;
pub mod sourcing;
pub mod templates;
pub mod test;
pub mod test_env;
static APP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));
pub trait Status {
fn update(&self, status: &str);
}
impl Status for () {
fn update(&self, _: &str) {}
}
pub fn target() -> Result<&'static str, Error> {
use std::env::consts::*;
if OS == "windows" {
return Err(Error::UnsupportedPlatform { arch: ARCH, os: OS });
}
match ARCH {
"aarch64" => {
return match OS {
"macos" => Ok("aarch64-apple-darwin"),
_ => Ok("aarch64-unknown-linux-gnu"),
};
},
"x86_64" | "x86" => {
return match OS {
"macos" => Ok("x86_64-apple-darwin"),
_ => Ok("x86_64-unknown-linux-gnu"),
};
},
&_ => {},
}
Err(Error::UnsupportedPlatform { arch: ARCH, os: OS })
}
#[cfg(feature = "integration-tests")]
pub fn pop(
dir: &Path,
args: impl IntoIterator<Item = impl AsRef<OsStr>>,
) -> tokio::process::Command {
#[allow(deprecated)]
let mut command = tokio::process::Command::new(cargo_bin("pop"));
command.current_dir(dir).args(args);
println!("{command:?}");
command
}
pub fn resolve_port(preferred_port: Option<u16>) -> u16 {
if let Some(port) = preferred_port &&
TcpListener::bind(format!("127.0.0.1:{}", port)).is_ok()
{
return port;
}
TcpListener::bind("127.0.0.1:0")
.expect("Failed to bind to an available port")
.local_addr()
.expect("Failed to retrieve local address. This should never occur.")
.port()
}
pub struct SortedSlice<'a, T>(&'a mut [T]);
impl<'a, T> SortedSlice<'a, T> {
pub fn by(slice: &'a mut [T], f: impl FnMut(&T, &T) -> Ordering) -> Self {
slice.sort_by(f);
Self(slice)
}
pub fn by_key<K: Ord>(slice: &'a mut [T], f: impl FnMut(&T) -> K) -> Self {
slice.sort_by_key(f);
Self(slice)
}
}
impl<T> Deref for SortedSlice<'_, T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
&self.0[..]
}
}
pub mod call {
pub use contract_build::Verbosity;
pub use contract_extrinsics::{DisplayEvents, TokenMetadata};
pub use ink_env::DefaultEnvironment;
}
#[cfg(test)]
mod tests {
use super::*;
use anyhow::Result;
#[test]
fn target_works() -> Result<()> {
crate::command_mock::CommandMock::default().execute_sync(|| {
use std::{process::Command, str};
let output = Command::new("rustc").arg("-vV").output()?;
let output = str::from_utf8(&output.stdout)?;
let target_expected = output
.lines()
.find(|l| l.starts_with("host: "))
.map(|l| &l[6..])
.unwrap()
.to_string();
assert_eq!(target()?, target_expected);
Ok(())
})
}
#[test]
fn resolve_port_works() -> Result<()> {
let port = resolve_port(None);
let listener = TcpListener::bind(format!("127.0.0.1:{}", port));
assert!(listener.is_ok());
Ok(())
}
#[test]
fn resolve_port_skips_busy_preferred_port() -> Result<()> {
let listener = TcpListener::bind("127.0.0.1:0")?;
let busy_port = listener.local_addr()?.port();
let port = resolve_port(Some(busy_port));
assert_ne!(port, busy_port);
let listener = TcpListener::bind(format!("127.0.0.1:{}", port));
assert!(listener.is_ok());
Ok(())
}
#[test]
fn sorted_slice_sorts_by_function() {
let mut values = ["one", "two", "three"];
let sorted = SortedSlice::by(values.as_mut_slice(), |a, b| a.cmp(b));
assert_eq!(*sorted, ["one", "three", "two"]);
}
#[test]
fn sorted_slice_sorts_by_key() {
let mut values = ['c', 'b', 'a'];
let sorted = SortedSlice::by_key(values.as_mut_slice(), |v| *v as u8);
assert_eq!(*sorted, ['a', 'b', 'c']);
}
}