#[ allow( clippy ::std_instead_of_alloc, clippy ::std_instead_of_core ) ]
mod private
{
use crate :: *;
use std ::fmt :: { Display, Formatter };
use std ::fs ::OpenOptions;
use std ::io ::
{
Read,
Seek,
SeekFrom,
Write
};
use std ::path ::PathBuf;
use regex ::Regex;
use entity :: { PathError, WorkspaceInitError };
#[ allow( unused_imports ) ]
use error ::
{
};
use workspace_md_extension ::WorkspaceMdExtension;
static TAGS_TEMPLATE: std ::sync ::OnceLock< Regex > = std ::sync ::OnceLock ::new();
fn regexes_initialize()
{
TAGS_TEMPLATE.set
(
Regex ::new
(
r"< !--\{ generate\.main_header\.start(\(\)|\{\}|\(.*?\)|\{.*?\}) \}-- >(.|\n|\r\n)+< !--\{ generate\.main_header\.end \}-- >"
)
.unwrap()
).ok();
}
#[ derive( Debug, Default, Clone ) ]
pub struct MainHeaderRenewReport
{
found_file: Option< PathBuf >,
touched_file: PathBuf,
success: bool,
}
impl Display for MainHeaderRenewReport
{
#[ allow( clippy ::collapsible_else_if ) ]
fn fmt( &self, f: &mut Formatter< '_ > ) -> std ::fmt ::Result
{
if self.success
{
if let Some( file_path ) = self.touched_file.to_str()
{
writeln!( f, "File successful changed: {file_path}." )?;
}
else
{
writeln!( f, "File successful changed but contains non-UTF-8 characters." )?;
}
}
else
{
if let Some( Some( file_path ) ) = self
.found_file
.as_ref()
.map( | p | p.to_str() )
{
writeln!( f, "File found but not changed: {file_path}." )?;
}
else
{
writeln!( f, "File not found or contains non-UTF-8 characters." )?;
}
}
std ::fmt ::Result ::Ok( () )
}
}
#[ derive( Debug, error ::Error ) ]
pub enum MainHeaderRenewError
{
#[ error( "Common error: {0}" ) ]
Common( #[ from ] error ::untyped ::Error ), #[ error( "I/O error: {0}" ) ]
IO( #[ from ] std ::io ::Error ),
#[ error( "Workspace error: {0}" ) ]
Workspace( #[ from ] WorkspaceInitError ),
#[ error( "Directory error: {0}" ) ]
Directory( #[ from ] PathError ),
}
struct HeaderParameters
{
master_branch: String,
repository_url: String,
workspace_name: String,
discord_url: Option< String >,
}
impl HeaderParameters
{
fn from_cargo_toml( workspace: &Workspace ) -> Result< Self, MainHeaderRenewError >
{
let repository_url = workspace
.repository_url()
.ok_or_else :: < error ::untyped ::Error, _ >
( || error ::untyped ::format_err!( "repo_url not found in workspace Cargo.toml" ) )?;
let master_branch = workspace.master_branch().unwrap_or( "master".into() );
let workspace_name = workspace
.workspace_name()
.ok_or_else :: < error ::untyped ::Error, _ >
( || error ::untyped ::format_err!( "workspace_name not found in workspace Cargo.toml" ) )?;
let discord_url = workspace.discord_url();
Result ::Ok
(
Self
{
master_branch,
repository_url,
workspace_name,
discord_url,
}
)
}
#[ allow( clippy ::uninlined_format_args, clippy ::wrong_self_convention ) ]
fn to_header( self ) -> Result< String, MainHeaderRenewError >
{
let discord = self.discord_url
.map
(
| discord |
format!
(
"\n[]({})",
discord
)
)
.unwrap_or_default();
Result ::Ok
(
format!
(
r"[](https: //github.com/{}/actions/workflows/standard_rust_scheduled.yml){}
[](https: //gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2F{}_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20{}_trivial_sample/https: //github.com/{})
[](https: //docs.rs/{})",
self.workspace_name,
url ::git_info_extract( &self.repository_url )?,
self.workspace_name,
self.master_branch,
url ::git_info_extract( &self.repository_url )?,
discord,
self.workspace_name.to_lowercase(), self.workspace_name.to_lowercase(), url ::git_info_extract( &self.repository_url )?,
self.workspace_name,
)
)
}
}
#[ allow( clippy ::uninlined_format_args ) ]
pub fn action( crate_dir: CrateDir )
-> ResultWithReport< MainHeaderRenewReport, MainHeaderRenewError >
{
let mut report = MainHeaderRenewReport ::default();
regexes_initialize();
let workspace = Workspace ::try_from
(
crate_dir
)
.err_with_report( &report )?;
let workspace_root = workspace
.workspace_root();
let header_param = HeaderParameters ::from_cargo_toml( &workspace )
.err_with_report( &report )?;
let read_me_path = workspace_root.join
(
repository ::readme_path( &workspace_root )
.err_with_report( &report )?
)
.err_with_report( &report )?;
report.found_file = Some( read_me_path.clone().to_path_buf() );
let mut file = OpenOptions ::new()
.read( true )
.write( true )
.open( &read_me_path )
.err_with_report( &report )?;
let mut content = String ::new();
file.read_to_string( &mut content ).err_with_report( &report )?;
let raw_params = TAGS_TEMPLATE
.get()
.unwrap()
.captures( &content )
.and_then( | c | c.get( 1 ) )
.map( | m | m.as_str() )
.unwrap_or_default();
let header = header_param.to_header().err_with_report( &report )?;
let content: String = TAGS_TEMPLATE.get().unwrap().replace
(
&content,
&format!
(
"< !--{{ generate.main_header.start{} }}-- >\n{}\n< !--{{ generate.main_header.end }}-- >",
raw_params,
header,
)
).into();
file.set_len( 0 ).err_with_report( &report )?;
file.seek( SeekFrom ::Start( 0 ) ).err_with_report( &report )?;
file.write_all( content.as_bytes() ).err_with_report( &report )?;
report.touched_file = read_me_path.to_path_buf();
report.success = true;
Result ::Ok( report )
}
}
crate ::mod_interface!
{
own use action;
orphan use MainHeaderRenewReport;
orphan use MainHeaderRenewError;
}