@@ -547,9 +547,28 @@ async fn tag_autocomplete(ctx: Context<'_>, partial_tag: &str) -> Vec<TagName> {
547
547
. unwrap_or_else ( |_| Vec :: new ( ) )
548
548
}
549
549
550
+ fn interpolate < ' a > ( template : & str , mut params : impl Iterator < Item = & ' a str > ) -> String {
551
+ let mut buf = String :: with_capacity ( template. len ( ) / 2 ) ;
552
+ for chunk in template. split ( "%%" ) {
553
+ let mut chunks = chunk. split ( "%s" ) ;
554
+ buf += chunks. next ( ) . unwrap ( ) ;
555
+ for chunk in chunks {
556
+ buf += params. next ( ) . unwrap_or ( "%s" ) ;
557
+ buf += chunk;
558
+ }
559
+ buf += "%" ;
560
+ }
561
+ // Remove last `%`.
562
+ buf. pop ( ) ;
563
+ buf
564
+ }
565
+
550
566
/// Print the content of a tag by name.
551
567
///
552
- /// Syntax: `?tag <tag name>`
568
+ /// Syntax: `?tag <tag name> <parameters...>`
569
+ ///
570
+ /// If the tag has placeholders (set with `%s`),
571
+ /// then you can fill them with the subsequent arguments.
553
572
///
554
573
/// Note that tags are local to the guild.
555
574
#[ poise:: command( prefix_command, slash_command, track_edits) ]
@@ -559,6 +578,7 @@ async fn tag(
559
578
#[ description = "The tag to print" ]
560
579
#[ autocomplete = "tag_autocomplete" ]
561
580
TagName ( tag_name) : TagName ,
581
+ #[ description = "Any parameters for the tag" ] parameters : Vec < String > ,
562
582
) -> Result < ( ) , PoiseError > {
563
583
let database = & ctx. data ( ) . database ;
564
584
let guild_id = ctx. guild_id ( ) . ok_or ( "no guild id, so no tags" ) ?. get ( ) ;
@@ -571,6 +591,7 @@ async fn tag(
571
591
. map ( |row| row. get :: < _ , String > ( "text" ) )
572
592
. transpose ( ) ?;
573
593
let text = text. unwrap_or_else ( || "That tag is not defined." . into ( ) ) ;
594
+ let text = interpolate ( & text, parameters. iter ( ) . map ( String :: as_str) ) ;
574
595
ctx. say ( text) . await ?;
575
596
Ok ( ( ) )
576
597
}
0 commit comments