Skip to content

Repository files navigation

FString is an extremely rough implementation of a compile-time generator for zero-allocation format strings with localization support. You can take a $"..." format string from your C#, copy-paste it into an .fstring file, and run the generator to produce a .cs file you can include into your application, like this:

Tooltip_CanUseInTurns(intcooldownTurnsLeft)= $" $[color:#FF0000]In $[.medium]{cooldownTurnsLeft} turn(s)$[.regular]$[]";

produces

publicstructTooltip_CanUseInTurns:IFString{publicstringName=>"Tooltip_CanUseInTurns";publicintcooldownTurnsLeft;publicvoidEmitValue(refFStringBuilderoutput,stringid){switch(id){case"cooldownTurnsLeft":output.Append(cooldownTurnsLeft);return;default:thrownewArgumentOutOfRangeException(nameof(id));}}publicvoidAppendTo(refFStringBuilderoutput,FStringDefinitiondefinition)=>definition.AppendTo(refthis,refoutput);publicvoidAppendTo(StringBuilderoutput){varfsb=newFStringBuilder(output);FStringTable.Default.Get(Name).AppendTo(refthis,reffsb);}publicoverridestringToString(){varoutput=newFStringBuilder();AppendTo(refoutput,FStringTable.Default.Get(Name));returnoutput.ToString();}}

which you use by constructing an instance of the struct and then calling AppendTo or ToString. The generator produces an xml string table at the same time, and you can load alternate string tables on demand for other cultures.

If you have multiple format strings that use the same arguments, you can group them:

(CombatStatstat,floatamount,stringresetStyle){FormatStat_Health=$"$[.medium]$[color:red] {amount}%{resetStyle}";FormatStat_Stamina=$"$[.medium]$(combat:Stamina|\uF800{amount}){resetStyle}";FormatStat_Initiative=$"$[.medium]$(combat:Initiative|\uF801{amount}){resetStyle}";FormatStat_Default=$"$[.medium]{amount}$[.regular] {stat}{resetStyle}";}

Basic support for switch statements is available, using syntax like the following:

(ICombatParticipantCaster,ActionDefinitionDefinition,boolconfirmed){
Action_CombatLog_Failed =switch(confirmed){
true =$"{Caster} failed to use {Definition.Name}: Confirmation failed";
false = $"{Caster} failed to use {Definition.Name}: No valid targets";}}

For simple automatic integration, use the .targets file by adding an import like this to your .csproj:

 <ImportProject="..\..\FString\FString.targets" />

And then add an ItemGroup pointing to your .fstring file(s) along with the output of the compiler:

 <ItemGroup>
<FStringTableInclude="FStrings\*.fstring" />
<!-- visual studio is bad software so we can't do this automatically for you -->
<CompileInclude="$(FStringOutputPath)\*.cs" />
</ItemGroup>

The compiler produces a static class named FStrings containing a static method or struct for each of your strings.

At startup, you'll want to load an appropriate string table for the current culture, like so:

publicstaticvoidLoadDefaultStringTable(){varculture=CultureInfo.CurrentCulture.ThreeLetterISOLanguageName;varpath=Path.Combine(ApplicationDirectory,$"FStringTable_{culture}.xml");using(varstream=File.OpenRead(path))Squared.FString.FStringTable.Default=newSquared.FString.FStringTable(culture,stream);}

About

C# localizable zero-allocation format string generator

Resources

Stars

16 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages