use core::fmt;
use clap::{Parser, Subcommand};
use stylus_core;
#[doc(hidden)]
pub mod internal;
const DEFAULT_LICENSE: &str = "MIT-OR-APACHE-2.0";
const DEFAULT_PRAGMA: &str = "pragma solidity ^0.8.23;";
#[derive(Parser)]
struct ExportCLI {
#[command(subcommand)]
commands: Option<ExportCommands>,
}
#[derive(Subcommand)]
enum ExportCommands {
Abi {
#[arg(long, default_value = DEFAULT_LICENSE)]
license: String,
#[arg(long, default_value = DEFAULT_PRAGMA)]
pragma: String,
},
Constructor,
}
pub fn handle_license_and_pragma() {
let args = ExportCLI::parse();
match args.commands {
None => {
print_license_and_pragma(DEFAULT_LICENSE, DEFAULT_PRAGMA);
}
Some(ExportCommands::Abi { license, pragma }) => {
print_license_and_pragma(&license, &pragma);
}
_ => {}
}
}
pub fn print_from_args<T: GenerateAbi>() {
let args = ExportCLI::parse();
match args.commands {
None => {
print!("{}", AbiPrinter(T::fmt_abi));
}
Some(ExportCommands::Abi {
license: _,
pragma: _,
}) => {
print!("{}", AbiPrinter(T::fmt_abi));
}
Some(ExportCommands::Constructor) => {
print_constructor_signature::<T>();
}
}
}
pub trait GenerateAbi {
const NAME: &'static str;
fn fmt_abi(f: &mut fmt::Formatter<'_>) -> fmt::Result;
fn fmt_constructor_signature(f: &mut fmt::Formatter<'_>) -> fmt::Result;
}
struct AbiPrinter(fn(&mut fmt::Formatter<'_>) -> fmt::Result);
impl fmt::Display for AbiPrinter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0(f)
}
}
pub fn print_license_and_pragma(license: &str, pragma: &str) {
println!("/**");
println!(" * This file was automatically generated by Stylus and represents a Rust program.");
println!(" * For more information, please see [The Stylus SDK](https://github.com/OffchainLabs/stylus-sdk-rs).");
println!(" */");
println!();
println!("// SPDX-License-Identifier: {license}");
println!("{pragma}");
println!();
}
fn print_constructor_signature<T: GenerateAbi>() {
print!("{}", AbiPrinter(T::fmt_constructor_signature));
}
pub fn underscore_if_sol(name: &str) -> String {
let underscore = || format!(" _{name}");
if stylus_core::is_sol_keyword(name) {
return underscore();
}
match name {
"" => "".to_string(),
_ => format!(" {name}"),
}
}