1#![doc = include_str!("../README.md")]
4
5pub use account_id::{parse_account, parse_h160_account};
6#[cfg(feature = "integration-tests")]
7use assert_cmd::cargo::cargo_bin;
8pub use build::Profile;
9pub use errors::Error;
10pub use git::{Git, GitHub, Release};
11pub use helpers::{
12 get_project_name_from_path, get_relative_or_absolute_path, prefix_with_current_dir_if_needed,
13 replace_in_file,
14};
15pub use manifest::{add_crate_to_workspace, find_workspace_toml};
16pub use metadata::format_type;
17pub use signer::create_signer;
18pub use sourcing::set_executable_permission;
19use std::{cmp::Ordering, net::TcpListener, ops::Deref};
20#[cfg(feature = "integration-tests")]
21use std::{ffi::OsStr, path::Path, process::Command};
22pub use subxt::{Config, PolkadotConfig as DefaultConfig};
23pub use subxt_signer::sr25519::Keypair;
24pub use templates::extractor::extract_template_files;
25pub use test::test_project;
26
27pub mod account_id;
29pub(crate) mod api;
31pub mod build;
33pub mod errors;
35pub mod git;
37pub mod helpers;
39pub mod manifest;
41pub mod metadata;
43pub mod polkadot_sdk;
45pub mod signer;
47pub mod sourcing;
49pub mod templates;
51pub mod test;
53pub mod test_env;
55
56static APP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));
57
58pub trait Status {
60 fn update(&self, status: &str);
62}
63
64impl Status for () {
65 fn update(&self, _: &str) {}
67}
68
69pub fn target() -> Result<&'static str, Error> {
71 use std::env::consts::*;
72
73 if OS == "windows" {
74 return Err(Error::UnsupportedPlatform { arch: ARCH, os: OS });
75 }
76
77 match ARCH {
78 "aarch64" =>
79 return match OS {
80 "macos" => Ok("aarch64-apple-darwin"),
81 _ => Ok("aarch64-unknown-linux-gnu"),
82 },
83 "x86_64" | "x86" =>
84 return match OS {
85 "macos" => Ok("x86_64-apple-darwin"),
86 _ => Ok("x86_64-unknown-linux-gnu"),
87 },
88 &_ => {},
89 }
90 Err(Error::UnsupportedPlatform { arch: ARCH, os: OS })
91}
92
93#[cfg(feature = "integration-tests")]
94pub fn pop(dir: &Path, args: impl IntoIterator<Item = impl AsRef<OsStr>>) -> Command {
95 let mut command = Command::new(cargo_bin("pop"));
96 command.current_dir(dir).args(args);
97 println!("{command:?}");
98 command
99}
100
101pub fn find_free_port(preferred_port: Option<u16>) -> u16 {
103 if let Some(port) = preferred_port {
105 if TcpListener::bind(format!("127.0.0.1:{}", port)).is_ok() {
106 return port;
107 }
108 }
109
110 TcpListener::bind("127.0.0.1:0")
112 .expect("Failed to bind to an available port")
113 .local_addr()
114 .expect("Failed to retrieve local address. This should never occur.")
115 .port()
116}
117
118pub struct SortedSlice<'a, T>(&'a mut [T]);
120impl<'a, T> SortedSlice<'a, T> {
121 pub fn by(slice: &'a mut [T], f: impl FnMut(&T, &T) -> Ordering) -> Self {
127 slice.sort_by(f);
128 Self(slice)
129 }
130
131 pub fn by_key<K: Ord>(slice: &'a mut [T], f: impl FnMut(&T) -> K) -> Self {
138 slice.sort_by_key(f);
139 Self(slice)
140 }
141}
142
143impl<T> Deref for SortedSlice<'_, T> {
144 type Target = [T];
145
146 fn deref(&self) -> &Self::Target {
147 &self.0[..]
148 }
149}
150
151pub mod call {
153 pub use contract_build::Verbosity;
157 pub use contract_extrinsics::{DisplayEvents, TokenMetadata};
158 pub use ink_env::DefaultEnvironment;
159}
160
161#[cfg(test)]
162mod tests {
163 use super::*;
164 use anyhow::Result;
165
166 #[test]
167 fn target_works() -> Result<()> {
168 use std::{process::Command, str};
169 let output = Command::new("rustc").arg("-vV").output()?;
170 let output = str::from_utf8(&output.stdout)?;
171 let target_expected = output
172 .lines()
173 .find(|l| l.starts_with("host: "))
174 .map(|l| &l[6..])
175 .unwrap()
176 .to_string();
177 assert_eq!(target()?, target_expected);
178 Ok(())
179 }
180
181 #[test]
182 fn find_free_port_works() -> Result<()> {
183 let port = find_free_port(None);
184 let addr = format!("127.0.0.1:{}", port);
185 let listener = TcpListener::bind(&addr);
187 assert!(listener.is_ok());
188 Ok(())
189 }
190
191 #[test]
192 fn sorted_slice_sorts_by_function() {
193 let mut values = ["one", "two", "three"];
194 let sorted = SortedSlice::by(values.as_mut_slice(), |a, b| a.cmp(b));
195 assert_eq!(*sorted, ["one", "three", "two"]);
196 }
197
198 #[test]
199 fn sorted_slice_sorts_by_key() {
200 let mut values = ['c', 'b', 'a'];
201 let sorted = SortedSlice::by_key(values.as_mut_slice(), |v| *v as u8);
202 assert_eq!(*sorted, ['a', 'b', 'c']);
203 }
204}