1#![doc = include_str!("../README.md")]
4
5pub use account_id::{parse_account, parse_h160_account};
6#[cfg(feature = "integration-tests")]
7#[allow(deprecated)]
8use assert_cmd::cargo::cargo_bin;
9pub use build::Profile;
10pub use errors::Error;
11pub use git::{Git, GitHub, Release};
12pub use helpers::{get_project_name_from_path, get_relative_or_absolute_path, replace_in_file};
13pub use metadata::format_type;
14pub use signer::create_signer;
15pub use sourcing::set_executable_permission;
16use std::{cmp::Ordering, net::TcpListener, ops::Deref};
17#[cfg(feature = "integration-tests")]
18use std::{ffi::OsStr, path::Path, process::Command};
19pub use subxt::{Config, PolkadotConfig as DefaultConfig};
20pub use subxt_signer::sr25519::Keypair;
21pub use templates::extractor::extract_template_files;
22pub use test::test_project;
23
24pub mod account_id;
26pub(crate) mod api;
28pub mod build;
30pub mod errors;
32pub mod git;
34pub mod helpers;
36pub mod manifest;
38pub mod metadata;
40pub mod polkadot_sdk;
42pub mod signer;
44pub mod sourcing;
46pub mod templates;
48pub mod test;
50pub mod test_env;
52
53static APP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));
54
55pub trait Status {
57 fn update(&self, status: &str);
59}
60
61impl Status for () {
62 fn update(&self, _: &str) {}
64}
65
66pub fn target() -> Result<&'static str, Error> {
68 use std::env::consts::*;
69
70 if OS == "windows" {
71 return Err(Error::UnsupportedPlatform { arch: ARCH, os: OS });
72 }
73
74 match ARCH {
75 "aarch64" => {
76 return match OS {
77 "macos" => Ok("aarch64-apple-darwin"),
78 _ => Ok("aarch64-unknown-linux-gnu"),
79 };
80 },
81 "x86_64" | "x86" => {
82 return match OS {
83 "macos" => Ok("x86_64-apple-darwin"),
84 _ => Ok("x86_64-unknown-linux-gnu"),
85 };
86 },
87 &_ => {},
88 }
89 Err(Error::UnsupportedPlatform { arch: ARCH, os: OS })
90}
91
92#[cfg(feature = "integration-tests")]
103pub fn pop(dir: &Path, args: impl IntoIterator<Item = impl AsRef<OsStr>>) -> Command {
104 #[allow(deprecated)]
105 let mut command = Command::new(cargo_bin("pop"));
106 command.current_dir(dir).args(args);
107 println!("{command:?}");
108 command
109}
110
111pub fn find_free_port(preferred_port: Option<u16>) -> u16 {
113 if let Some(port) = preferred_port &&
115 TcpListener::bind(format!("127.0.0.1:{}", port)).is_ok()
116 {
117 return port;
118 }
119
120 TcpListener::bind("127.0.0.1:0")
122 .expect("Failed to bind to an available port")
123 .local_addr()
124 .expect("Failed to retrieve local address. This should never occur.")
125 .port()
126}
127
128pub struct SortedSlice<'a, T>(&'a mut [T]);
130impl<'a, T> SortedSlice<'a, T> {
131 pub fn by(slice: &'a mut [T], f: impl FnMut(&T, &T) -> Ordering) -> Self {
137 slice.sort_by(f);
138 Self(slice)
139 }
140
141 pub fn by_key<K: Ord>(slice: &'a mut [T], f: impl FnMut(&T) -> K) -> Self {
148 slice.sort_by_key(f);
149 Self(slice)
150 }
151}
152
153impl<T> Deref for SortedSlice<'_, T> {
154 type Target = [T];
155
156 fn deref(&self) -> &Self::Target {
157 &self.0[..]
158 }
159}
160
161pub mod call {
163 pub use contract_build::Verbosity;
167 pub use contract_extrinsics::{DisplayEvents, TokenMetadata};
168 pub use ink_env::DefaultEnvironment;
169}
170
171#[cfg(test)]
172mod tests {
173 use super::*;
174 use anyhow::Result;
175
176 #[test]
177 fn target_works() -> Result<()> {
178 use std::{process::Command, str};
179 let output = Command::new("rustc").arg("-vV").output()?;
180 let output = str::from_utf8(&output.stdout)?;
181 let target_expected = output
182 .lines()
183 .find(|l| l.starts_with("host: "))
184 .map(|l| &l[6..])
185 .unwrap()
186 .to_string();
187 assert_eq!(target()?, target_expected);
188 Ok(())
189 }
190
191 #[test]
192 fn find_free_port_works() -> Result<()> {
193 let port = find_free_port(None);
194 let addr = format!("127.0.0.1:{}", port);
195 let listener = TcpListener::bind(&addr);
197 assert!(listener.is_ok());
198 Ok(())
199 }
200
201 #[test]
202 fn sorted_slice_sorts_by_function() {
203 let mut values = ["one", "two", "three"];
204 let sorted = SortedSlice::by(values.as_mut_slice(), |a, b| a.cmp(b));
205 assert_eq!(*sorted, ["one", "three", "two"]);
206 }
207
208 #[test]
209 fn sorted_slice_sorts_by_key() {
210 let mut values = ['c', 'b', 'a'];
211 let sorted = SortedSlice::by_key(values.as_mut_slice(), |v| *v as u8);
212 assert_eq!(*sorted, ['a', 'b', 'c']);
213 }
214}