#!/usr/bin/env dub
/+ dub.sdl:
name "box"
dependency "sparkles:core-cli" path="../../.."
targetPath "build"
// Optimised, assertions live, `debug {}` blocks out — the build every nix
// artifact uses. Neither `debug` (which compiles those blocks in) nor
// `release` (which deletes assert *expressions*, side effects included).
buildType "checked" {
buildOptions "optimize" "inline" "debugInfo"
}
+/
import (package) stdstd.(module) std.algorithmThis package implements generic algorithms oriented towards the processing of
sequences. Sequences processed by these functions define range-based
interfaces. See also Reference on ranges and
tutorial on ranges.
Algorithms are categorized into the following submodules:
Submodule Functions
| Searching |
all
any
balancedParens
boyerMooreFinder
canFind
commonPrefix
count
countUntil
endsWith
find
findAdjacent
findAmong
findSkip
findSplit
findSplitAfter
findSplitBefore
minCount
maxCount
minElement
maxElement
minIndex
maxIndex
minPos
maxPos
skipOver
startsWith
until
|
| Comparison |
among
castSwitch
clamp
cmp
either
equal
isPermutation
isSameLength
levenshteinDistance
levenshteinDistanceAndPath
max
min
mismatch
predSwitch
|
| Iteration |
cache
cacheBidirectional
chunkBy
cumulativeFold
each
filter
filterBidirectional
fold
group
joiner
map
mean
permutations
reduce
splitWhen
splitter
substitute
sum
uniq
|
| Sorting |
completeSort
isPartitioned
isSorted
isStrictlyMonotonic
ordered
strictlyOrdered
makeIndex
merge
multiSort
nextEvenPermutation
nextPermutation
nthPermutation
partialSort
partition
partition3
schwartzSort
sort
topN
topNCopy
topNIndex
|
| Set operations (setops) |
cartesianProduct
largestPartialIntersection
largestPartialIntersectionWeighted
multiwayMerge
multiwayUnion
setDifference
setIntersection
setSymmetricDifference
|
| Mutation |
bringToFront
copy
fill
initializeAll
move
moveAll
moveSome
moveEmplace
moveEmplaceAll
moveEmplaceSome
remove
reverse
strip
stripLeft
stripRight
swap
swapRanges
uninitializedFill
|
Many functions in this package are parameterized with a predicate.
The predicate may be any suitable callable type
(a function, a delegate, a functor, or a lambda), or a
compile-time string. The string may consist of any legal D
expression that uses the symbol a (for unary functions) or the
symbols a and b (for binary functions). These names will NOT
interfere with other homonym symbols in user code because they are
evaluated in a different context. The default for all binary
comparison predicates is "a == b" for unordered operations and
"a < b" for ordered operations.
Example
int[] a = ...;
static bool greater(int a, int b)
{
return a > b;
}
sort!greater(a); // predicate as alias
sort!((a, b) => a > b)(a); // predicate as a lambda.
sort!"a > b"(a); // predicate as string
// (no ambiguity with array name)
sort(a); // no predicate, "a < b" is implicit
Source
std/algorithm/package.d
algorithm : (alias template) box.map = std.algorithm.iteration.map(fun...) if (fun.length >= 1)Implements the homonym function (also known as transform) present
in many languages of functional flavor. The call ``map!(fun)(range)
returns a range of which elements are obtained by applying fun(a)
left to right for all elements a in range. The original ranges are
not changed. Evaluation is done lazily.
map, (alias template) box.joiner = std.algorithm.iteration.joiner(RoR, Separator)(RoR r, Separator sep)Lazily joins a range of ranges with a separator. The separator itself
is a range. If a separator is not provided, then the ranges are
joined directly without anything in between them (often called flatten
in other languages).
Note
When both outer and inner ranges of RoR are bidirectional and the joiner is
iterated from the back to the front, the separator will still be consumed from
front to back, even if it is a bidirectional range too.
joiner;
import (package) stdstd.(module) std.convA one-stop shop for converting values from one type to another.
Category Functions Generic asOriginalType castFrom parse to toChars bitCast Strings text wtext dtext writeText writeWText writeDText hexString Numeric octal roundTo signed unsigned Exceptions ConvException ConvOverflowException
Source
std/conv.d
conv : (alias template) box.to = std.conv.to(T)The to template converts a value from one type to another.
The source type is deduced and the target type must be specified, for example the
expression to`!int(42.0)` converts the number 42 from
`double` to `int`. The conversion is "safe", i.e.,
it checks for overflow; to!int(4.2e10) would throw the
ConvOverflowException exception. Overflow checks are only
inserted when necessary, e.g., ``to!double(42) does not do
any checking because any int fits in a double.
Conversions from string to numeric types differ from the C equivalents
atoi() and atol() by checking for overflow and not allowing whitespace.
For conversion of strings to signed types, the grammar recognized is:
Integer:
Sign UnsignedInteger
UnsignedInteger
Sign:
+
-
For conversion to unsigned types, the grammar recognized is:
UnsignedInteger:
DecimalDigit
DecimalDigit UnsignedInteger
to;
import (package) sparklessparkles.(package) sparkles.uiui.(package) sparkles.ui.componentscomponents.(module) sparkles.ui.components.boxbox : (alias) box.drawBox = string sparkles.ui.components.box.drawBox(string[] content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))drawBox, (struct) sparkles.ui.components.box.BoxPropsBoxProps, (enum) sparkles.ui.components.box.TitleOverflowHow a title too wide for maxWidth is handled. Only takes effect when
maxWidth > 0; with no cap the box always expands to fit the title.
TitleOverflow;
import (package) sparklessparkles.(package) sparkles.uiui.(package) sparkles.ui.componentscomponents.(module) sparkles.ui.components.demoDemo runner utilities for showcasing UI components.
Provides a structured way to display multiple sections with headers,
useful for examples and demonstrations.
demo : (struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section, (alias) box.runDemo = void sparkles.ui.components.demo.runDemo(string header, sparkles.ui.components.demo.Section[] content, sparkles.ui.components.demo.DemoProps props = DemoProps(67LU, "Demo Complete")) @safeRuns a demo by printing a header banner, sections, and closing banner.
Example
runDemo(
header: "My Demo",
content: [
Section(header: "First", content: "Some content here"),
Section(header: "Second", content: "More content"),
],
);
runDemo;
import (package) sparklessparkles.(package) sparkles.uiui.(package) sparkles.ui.componentscomponents.(module) sparkles.ui.components.tableThe span-capable table: pure model resolution in
sparkles.ui.components.table.grid, the content-agnostic layout core
(configuration, width/height solving, junction glyphs, line ordering) in
sparkles.ui.components.table.layout, and the string view in
sparkles.ui.components.table.render, re-exported here under the historical
module name. Nothing else lives in this file — the test runner does not
discover unittests in package.d modules.
The widget view (sparkles.ui.components.table.widgets) is deliberately
not re-exported: it imports the whole toolkit — canvas, chrome, state,
widget, wrap — where the three modules above reach no further than
sparkles:base. Re-exporting it would put that closure on every consumer of
drawTable, including the wasm playground, which compiles a hand-listed set
of source directories and fails outright when the closure widens. Import it by
its own module path where the widget view is actually wanted.
table : (alias) box.drawTable = string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))Render a rectangular string[][] as a boxed table. With the default
TableProps the output is byte-identical to the pre-overhaul renderer.
drawTable;
import (package) sparklessparkles.(package) sparkles.basebase.(module) sparkles.base.term_styleterm_style : (enum) sparkles.base.term_style.StyleStyle, (alias) box.stylize = string sparkles.base.term_style.stylize(string text, sparkles.base.term_style.Style style, bool resetAfter = true) pure nothrow @safestylize, (alias) box.styleSample = string sparkles.base.term_style.styleSample(sparkles.base.term_style.Style style, bool resetAfter = true) pure nothrow @safeReturns the name of a Style styled with that style.
Useful for displaying style palettes where styles demonstrate themselves.
Example
``styleSample(Style.red) returns "red" rendered in red.
styleSample;
import (package) sparklessparkles.(package) sparkles.basebase.(module) sparkles.base.styled_templateStyle template processing for IES (Interpolated Expression Sequences).
Provides a template syntax for applying terminal styles to IES strings:
import sparkles.base.styled_template;
int cpu = 75;
styledWriteln(i"CPU: {red $(cpu)%} Status: {green OK}");
Supported syntax:
{red text} — Apply single style
{bold.red text} — Chain multiple styles
{bold outer {red nested}} — Nested blocks (inner inherits outer)
{red text {~red normal}} — Negation with ~ removes a style
#{ — Escaped literal {
#} — Escaped literal }
styled_template : (alias template) box.styledText = sparkles.base.styled_template.styledText(Args...)(ColorDepth depth, InterpolationHeader header, Args args, InterpolationFooter footer)Returns styled IES as a string; depth folds colors to the terminal's tier.
styledText;
import (package) sparklessparkles.(package) sparkles.basebase.(module) sparkles.base.prettyprintprettyprint : (alias template) box.prettyPrint = sparkles.base.prettyprint.prettyPrint(T, Hook = void)(in T value, in PrettyPrintOptions!Hook opt = PrettyPrintOptions!Hook())Convenience overload that returns a string.
prettyPrint, (alias struct) box.PrettyPrintOptions = sparkles.base.prettyprint.PrettyPrintOptions(SourceUriHook = void)PrettyPrintOptions;
struct (struct) box.ConfigConfig
{
(alias) object.string = stringstring (field) string box.Config.hosthost;
int (field) int box.Config.portport;
bool (field) bool box.Config.sslssl;
(alias) object.string = stringstring[] (field) string[] box.Config.endpointsendpoints;
}
struct (struct) box.ServerServer
{
(alias) object.string = stringstring (field) string box.Server.namename;
(alias) object.string = stringstring (field) string box.Server.ipip;
int (field) int box.Server.portport;
}
struct (struct) box.ClusterCluster
{
(alias) object.string = stringstring (field) string box.Cluster.namename;
(struct) box.ServerServer[] (field) box.Server[] box.Cluster.serversservers;
bool (field) bool box.Cluster.activeactive;
}
void void D main()main()
{
void sparkles.ui.components.demo.runDemo(string header, sparkles.ui.components.demo.Section[] content, sparkles.ui.components.demo.DemoProps props = DemoProps(67LU, "Demo Complete")) @safeRuns a demo by printing a header banner, sections, and closing banner.
Example
runDemo(
header: "My Demo",
content: [
Section(header: "First", content: "Some content here"),
Section(header: "Second", content: "More content"),
],
);
Examples
Section initialization
const section = Section(header: "Title", content: "Body text");
assert(section.header == "Title");
assert(section.content == "Body text");
DemoProps defaults
const props = DemoProps.init;
assert(props.width == 67);
assert(props.endTitle == "Demo Complete");
runDemo(
header: "drawBox Demo - All Features",
content: [
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "Simple Box",
content: ["1"]
.string sparkles.ui.components.box.drawBox(string[] content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))drawBox("1"),
),
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "Box with Styled Content",
content: [
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Status: }{green Running}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Status: }{green Running}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{bold Status: }{green Running}"),
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Mode: }{yellow Production}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Mode: }{yellow Production}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{bold Mode: }{yellow Production}"),
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Health: }{brightGreen Healthy}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Health: }{brightGreen Healthy}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{bold Health: }{brightGreen Healthy}"),
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Uptime: }{cyan 3 days, 14 hours}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Uptime: }{cyan 3 days, 14 hours}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{bold Uptime: }{cyan 3 days, 14 hours}"),
].string sparkles.ui.components.box.drawBox(string[] content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))drawBox("Status"),
),
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "Box without Left Border",
content: ["This is line number 1", "This is line number 2", "This is line number 3"]
.string sparkles.ui.components.box.drawBox(string[] content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))drawBox("No Border", (struct) sparkles.ui.components.box.BoxPropsBoxProps(omitLeftBorder: true)),
),
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "Box with Embedded Table",
content: [
["Name", "Age", "Role"],
["Alice", "30", "Engineer"],
["Bob", "25", "Designer"],
["Carol", "35", "Manager"],
].string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))Render a rectangular string[][] as a boxed table. With the default
TableProps the output is byte-identical to the pre-overhaul renderer.
drawTable.string sparkles.ui.components.box.drawBox(string content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))Overload that accepts a single string and splits it into lines internally.
drawBox("Team"),
),
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "Box with prettyPrint Output",
content: (struct) box.ConfigConfig(
host: "localhost",
port: 8080,
ssl: true,
endpoints: ["/api", "/health", "/metrics"],
).string sparkles.base.prettyprint.prettyPrint!(box.Config, void)(in box.Config value, in sparkles.base.prettyprint.PrettyPrintOptions!void opt = PrettyPrintOptions(cast(ushort)2u, cast(ushort)8u, 32u, 80u, true, false)) pure nothrow @safeConvenience overload that returns a string.
prettyPrint((template instance) sparkles.base.prettyprint.PrettyPrintOptions!voidPrettyPrintOptions!void(softMaxWidth: 0)).string sparkles.ui.components.box.drawBox(string content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))Overload that accepts a single string and splits it into lines internally.
drawBox("Config"),
),
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "Dashboard Example",
content: [
[string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Metric}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Metric}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{bold Metric}"), string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Value}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Value}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{bold Value}"), string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Status}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Status}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{bold Status}")],
["CPU Usage", "45%", string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{green OK}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{green OK}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{green OK}")],
["Memory", "2.1 GB", string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{green OK}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{green OK}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{green OK}")],
["Disk", "89%", string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{yellow Warning}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{yellow Warning}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{yellow Warning}")],
["Network", "1.2 Gbps", string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{green OK}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{green OK}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{green OK}")],
].string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))Render a rectangular string[][] as a boxed table. With the default
TableProps the output is byte-identical to the pre-overhaul renderer.
drawTable.string sparkles.ui.components.box.drawBox(string content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))Overload that accepts a single string and splits it into lines internally.
drawBox("Metrics"),
),
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "Color Palette Box",
content: [
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Foreground Colors:}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Foreground Colors:}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{bold Foreground Colors:}"),
" " ~ [(enum) sparkles.base.term_style.StyleStyle.(enum value) sparkles.base.term_style.Style.red = [31u, 39u]red, (enum) sparkles.base.term_style.StyleStyle.(enum value) sparkles.base.term_style.Style.green = [32u, 39u]green, (enum) sparkles.base.term_style.StyleStyle.(enum value) sparkles.base.term_style.Style.yellow = [33u, 39u]yellow, (enum) sparkles.base.term_style.StyleStyle.(enum value) sparkles.base.term_style.Style.blue = [34u, 39u]blue, (enum) sparkles.base.term_style.StyleStyle.(enum value) sparkles.base.term_style.Style.magenta = [35u, 39u]magenta, (enum) sparkles.base.term_style.StyleStyle.(enum value) sparkles.base.term_style.Style.cyan = [36u, 39u]cyan]
.std.algorithm.iteration.MapResult!(styleSample, Style[]) std.algorithm.iteration.map!(styleSample).map!(sparkles.base.term_style.Style[])(sparkles.base.term_style.Style[] r) pure nothrow @nogc @safeImplements the homonym function (also known as transform) present
in many languages of functional flavor. The call ``map!(fun)(range)
returns a range of which elements are obtained by applying fun(a)
left to right for all elements a in range. The original ranges are
not changed. Evaluation is done lazily.
Examples
import std.algorithm.comparison : equal;
import std.range : chain, only;
auto squares =
chain(only(1, 2, 3, 4), only(5, 6)).map!(a => a * a);
assert(equal(squares, only(1, 4, 9, 16, 25, 36)));
Multiple functions can be passed to map. In that case, the
element type of map is a tuple containing one element for each
function.
auto sums = [2, 4, 6, 8];
auto products = [1, 4, 9, 16];
size_t i = 0;
foreach (result; [ 1, 2, 3, 4 ].map!("a + a", "a * a"))
{
assert(result[0] == sums[i]);
assert(result[1] == products[i]);
++i;
}
You may alias map with some function(s) to a symbol and use
it separately:
import std.algorithm.comparison : equal;
import std.conv : to;
alias stringize = map!(to!string);
assert(equal(stringize([ 1, 2, 3, 4 ]), [ "1", "2", "3", "4" ]));
map!string sparkles.base.term_style.styleSample(sparkles.base.term_style.Style style, bool resetAfter = true) pure nothrow @safeReturns the name of a Style styled with that style.
Useful for displaying style palettes where styles demonstrate themselves.
Example
``styleSample(Style.red) returns "red" rendered in red.
Examples
assert(styleSample(Style.red) == "\x1b[31mred\x1b[39m");
assert(styleSample(Style.bold) == "\x1b[1mbold\x1b[22m");
assert(styleSample(Style.green, false) == "\x1b[32mgreen");
styleSample.std.algorithm.iteration.joiner!(MapResult!(styleSample, Style[]), string).Result std.algorithm.iteration.joiner!(std.algorithm.iteration.MapResult!(styleSample, Style[]), string)(std.algorithm.iteration.MapResult!(styleSample, Style[]) r, string sep) pure nothrow @safeLazily joins a range of ranges with a separator. The separator itself
is a range. If a separator is not provided, then the ranges are
joined directly without anything in between them (often called flatten
in other languages).
Note
When both outer and inner ranges of RoR are bidirectional and the joiner is
iterated from the back to the front, the separator will still be consumed from
front to back, even if it is a bidirectional range too.
Examples
import std.algorithm.comparison : equal;
import std.conv : text;
assert(["abc", "def"].joiner.equal("abcdef"));
assert(["Mary", "has", "a", "little", "lamb"]
.joiner("...")
.equal("Mary...has...a...little...lamb"));
assert(["", "abc"].joiner("xyz").equal("xyzabc"));
assert([""].joiner("xyz").equal(""));
assert(["", ""].joiner("xyz").equal("xyz"));
joiner(" ").string std.conv.to!string.to!(std.algorithm.iteration.joiner!(MapResult!(styleSample, Style[]), string).Result)(std.algorithm.iteration.joiner!(MapResult!(styleSample, Style[]), string).Result __param_0) pure @safeThe to template converts a value from one type to another.
The source type is deduced and the target type must be specified, for example the
expression to`!int(42.0)` converts the number 42 from
`double` to `int`. The conversion is "safe", i.e.,
it checks for overflow; to!int(4.2e10) would throw the
ConvOverflowException exception. Overflow checks are only
inserted when necessary, e.g., ``to!double(42) does not do
any checking because any int fits in a double.
Conversions from string to numeric types differ from the C equivalents
atoi() and atol() by checking for overflow and not allowing whitespace.
For conversion of strings to signed types, the grammar recognized is:
Integer:
Sign UnsignedInteger
UnsignedInteger
Sign:
+
-
For conversion to unsigned types, the grammar recognized is:
UnsignedInteger:
DecimalDigit
DecimalDigit UnsignedInteger
Examples
Converting a value to its own type (useful mostly for generic code)
simply returns its argument.
int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14
Converting among numeric types is a safe way to cast them around.
Conversions from floating-point types to integral types allow loss of
precision (the fractional part of a floating-point number). The
conversion is truncating towards zero, the same way a cast would
truncate. (To round a floating point value when casting to an
integral, use roundTo.)
import std.exception : assertThrown;
int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));
assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);
When converting strings to numeric types, note that D hexadecimal and binary
literals are not handled. Neither the prefixes that indicate the base, nor the
horizontal bar used to separate groups of digits are recognized. This also
applies to the suffixes that indicate the type.
To work around this, you can specify a radix for conversions involving numbers.
auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);
Conversions from integral types to floating-point types always
succeed, but might lose accuracy. The largest integers with a
predecessor representable in floating-point format are 2^24-1 for
float, 2^53-1 for double, and 2^64-1 for real (when
real is 80-bit, e.g. on Intel machines).
// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);
Conversion from string types to char types enforces the input
to consist of a single code point, and said code point must
fit in the target type. Otherwise, ConvException is thrown.
import std.exception : assertThrown;
assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');
// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');
// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));
Converting an array to another array type works by converting each
element in turn. Associative arrays can be converted to associative
arrays as long as keys and values can in turn be converted.
import std.string : split;
int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);
Conversions operate transitively, meaning that they work on arrays and
associative arrays of any complexity.
This conversion works because to`!short` applies to an `int`, to!wstring
applies to a string, to`!string` applies to a `double`, and
to!(double[]) applies to an int[]. The conversion might throw an
exception because ``to!short might fail the range check.
int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);
Object-to-object conversions by dynamic casting throw exception when
the source is non-null and the target is null.
import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));
Stringize conversion from all types is supported.
String to string conversion works for any two string types having
(char, wchar, dchar) character widths and any
combination of qualifiers (mutable, const, or immutable).
Converts array (other than strings) to string.
Each element is converted by calling ``to!T.
Associative array to string conversion.
Each element is converted by calling ``to!T.
Object to string conversion calls toString against the object or
returns "null" if the object is null.
Struct to string conversion calls toString against the struct if
it is defined.
For structs that do not define toString, the conversion to string
produces the list of fields.
Enumerated types are converted to strings as their symbolic names.
Boolean values are converted to "true" or "false".
char, wchar, dchar to a string type.
Unsigned or signed integers to strings.
: Convert integral value to string in radix radix.
radix must be a value from 2 to 36.
value is treated as a signed value only if radix is 10.
The characters A through Z are used to represent values 10 through 36
and their case is determined by the letterCase parameter.
All floating point types to all string types.
Pointer to string conversions convert the pointer to a size_t value.
If pointer is char*, treat it as C-style strings.
In that case, this function is @system.
See formatValue on how toString should be defined.
// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");
// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
to!string(associativeArray) == `["1":2, "0":1]`);
// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");
// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);
auto c = to!(wchar[])(b);
assert(c == "abcx");
Strings can be converted to enum types. The enum member with the same name as the
input string is returned. The comparison is case-sensitive.
A ConvException is thrown if the enum does not have the specified member.
import std.exception : assertThrown;
enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to!(alias) object.string = stringstring,
"",
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Bright Colors:}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Bright Colors:}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{bold Bright Colors:}"),
" " ~ [(enum) sparkles.base.term_style.StyleStyle.(enum value) sparkles.base.term_style.Style.brightRed = [91u, 39u]brightRed, (enum) sparkles.base.term_style.StyleStyle.(enum value) sparkles.base.term_style.Style.brightGreen = [92u, 39u]brightGreen, (enum) sparkles.base.term_style.StyleStyle.(enum value) sparkles.base.term_style.Style.brightYellow = [93u, 39u]brightYellow, (enum) sparkles.base.term_style.StyleStyle.(enum value) sparkles.base.term_style.Style.brightBlue = [94u, 39u]brightBlue]
.std.algorithm.iteration.MapResult!(styleSample, Style[]) std.algorithm.iteration.map!(styleSample).map!(sparkles.base.term_style.Style[])(sparkles.base.term_style.Style[] r) pure nothrow @nogc @safeImplements the homonym function (also known as transform) present
in many languages of functional flavor. The call ``map!(fun)(range)
returns a range of which elements are obtained by applying fun(a)
left to right for all elements a in range. The original ranges are
not changed. Evaluation is done lazily.
Examples
import std.algorithm.comparison : equal;
import std.range : chain, only;
auto squares =
chain(only(1, 2, 3, 4), only(5, 6)).map!(a => a * a);
assert(equal(squares, only(1, 4, 9, 16, 25, 36)));
Multiple functions can be passed to map. In that case, the
element type of map is a tuple containing one element for each
function.
auto sums = [2, 4, 6, 8];
auto products = [1, 4, 9, 16];
size_t i = 0;
foreach (result; [ 1, 2, 3, 4 ].map!("a + a", "a * a"))
{
assert(result[0] == sums[i]);
assert(result[1] == products[i]);
++i;
}
You may alias map with some function(s) to a symbol and use
it separately:
import std.algorithm.comparison : equal;
import std.conv : to;
alias stringize = map!(to!string);
assert(equal(stringize([ 1, 2, 3, 4 ]), [ "1", "2", "3", "4" ]));
map!string sparkles.base.term_style.styleSample(sparkles.base.term_style.Style style, bool resetAfter = true) pure nothrow @safeReturns the name of a Style styled with that style.
Useful for displaying style palettes where styles demonstrate themselves.
Example
``styleSample(Style.red) returns "red" rendered in red.
Examples
assert(styleSample(Style.red) == "\x1b[31mred\x1b[39m");
assert(styleSample(Style.bold) == "\x1b[1mbold\x1b[22m");
assert(styleSample(Style.green, false) == "\x1b[32mgreen");
styleSample.std.algorithm.iteration.joiner!(MapResult!(styleSample, Style[]), string).Result std.algorithm.iteration.joiner!(std.algorithm.iteration.MapResult!(styleSample, Style[]), string)(std.algorithm.iteration.MapResult!(styleSample, Style[]) r, string sep) pure nothrow @safeLazily joins a range of ranges with a separator. The separator itself
is a range. If a separator is not provided, then the ranges are
joined directly without anything in between them (often called flatten
in other languages).
Note
When both outer and inner ranges of RoR are bidirectional and the joiner is
iterated from the back to the front, the separator will still be consumed from
front to back, even if it is a bidirectional range too.
Examples
import std.algorithm.comparison : equal;
import std.conv : text;
assert(["abc", "def"].joiner.equal("abcdef"));
assert(["Mary", "has", "a", "little", "lamb"]
.joiner("...")
.equal("Mary...has...a...little...lamb"));
assert(["", "abc"].joiner("xyz").equal("xyzabc"));
assert([""].joiner("xyz").equal(""));
assert(["", ""].joiner("xyz").equal("xyz"));
joiner(" ").string std.conv.to!string.to!(std.algorithm.iteration.joiner!(MapResult!(styleSample, Style[]), string).Result)(std.algorithm.iteration.joiner!(MapResult!(styleSample, Style[]), string).Result __param_0) pure @safeThe to template converts a value from one type to another.
The source type is deduced and the target type must be specified, for example the
expression to`!int(42.0)` converts the number 42 from
`double` to `int`. The conversion is "safe", i.e.,
it checks for overflow; to!int(4.2e10) would throw the
ConvOverflowException exception. Overflow checks are only
inserted when necessary, e.g., ``to!double(42) does not do
any checking because any int fits in a double.
Conversions from string to numeric types differ from the C equivalents
atoi() and atol() by checking for overflow and not allowing whitespace.
For conversion of strings to signed types, the grammar recognized is:
Integer:
Sign UnsignedInteger
UnsignedInteger
Sign:
+
-
For conversion to unsigned types, the grammar recognized is:
UnsignedInteger:
DecimalDigit
DecimalDigit UnsignedInteger
Examples
Converting a value to its own type (useful mostly for generic code)
simply returns its argument.
int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14
Converting among numeric types is a safe way to cast them around.
Conversions from floating-point types to integral types allow loss of
precision (the fractional part of a floating-point number). The
conversion is truncating towards zero, the same way a cast would
truncate. (To round a floating point value when casting to an
integral, use roundTo.)
import std.exception : assertThrown;
int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));
assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);
When converting strings to numeric types, note that D hexadecimal and binary
literals are not handled. Neither the prefixes that indicate the base, nor the
horizontal bar used to separate groups of digits are recognized. This also
applies to the suffixes that indicate the type.
To work around this, you can specify a radix for conversions involving numbers.
auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);
Conversions from integral types to floating-point types always
succeed, but might lose accuracy. The largest integers with a
predecessor representable in floating-point format are 2^24-1 for
float, 2^53-1 for double, and 2^64-1 for real (when
real is 80-bit, e.g. on Intel machines).
// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);
Conversion from string types to char types enforces the input
to consist of a single code point, and said code point must
fit in the target type. Otherwise, ConvException is thrown.
import std.exception : assertThrown;
assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');
// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');
// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));
Converting an array to another array type works by converting each
element in turn. Associative arrays can be converted to associative
arrays as long as keys and values can in turn be converted.
import std.string : split;
int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);
Conversions operate transitively, meaning that they work on arrays and
associative arrays of any complexity.
This conversion works because to`!short` applies to an `int`, to!wstring
applies to a string, to`!string` applies to a `double`, and
to!(double[]) applies to an int[]. The conversion might throw an
exception because ``to!short might fail the range check.
int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);
Object-to-object conversions by dynamic casting throw exception when
the source is non-null and the target is null.
import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));
Stringize conversion from all types is supported.
String to string conversion works for any two string types having
(char, wchar, dchar) character widths and any
combination of qualifiers (mutable, const, or immutable).
Converts array (other than strings) to string.
Each element is converted by calling ``to!T.
Associative array to string conversion.
Each element is converted by calling ``to!T.
Object to string conversion calls toString against the object or
returns "null" if the object is null.
Struct to string conversion calls toString against the struct if
it is defined.
For structs that do not define toString, the conversion to string
produces the list of fields.
Enumerated types are converted to strings as their symbolic names.
Boolean values are converted to "true" or "false".
char, wchar, dchar to a string type.
Unsigned or signed integers to strings.
: Convert integral value to string in radix radix.
radix must be a value from 2 to 36.
value is treated as a signed value only if radix is 10.
The characters A through Z are used to represent values 10 through 36
and their case is determined by the letterCase parameter.
All floating point types to all string types.
Pointer to string conversions convert the pointer to a size_t value.
If pointer is char*, treat it as C-style strings.
In that case, this function is @system.
See formatValue on how toString should be defined.
// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");
// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
to!string(associativeArray) == `["1":2, "0":1]`);
// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");
// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);
auto c = to!(wchar[])(b);
assert(c == "abcx");
Strings can be converted to enum types. The enum member with the same name as the
input string is returned. The comparison is case-sensitive.
A ConvException is thrown if the enum does not have the specified member.
import std.exception : assertThrown;
enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to!(alias) object.string = stringstring,
"",
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Styles:}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Styles:}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{bold Styles:}"),
" " ~ [(enum) sparkles.base.term_style.StyleStyle.(enum value) sparkles.base.term_style.Style.bold = [1u, 22u]bold, (enum) sparkles.base.term_style.StyleStyle.(enum value) sparkles.base.term_style.Style.dim = [2u, 22u]dim, (enum) sparkles.base.term_style.StyleStyle.(enum value) sparkles.base.term_style.Style.italic = [3u, 23u]italic, (enum) sparkles.base.term_style.StyleStyle.(enum value) sparkles.base.term_style.Style.underline = [4u, 24u]underline, (enum) sparkles.base.term_style.StyleStyle.(enum value) sparkles.base.term_style.Style.strikethrough = [9u, 29u]strikethrough]
.std.algorithm.iteration.MapResult!(styleSample, Style[]) std.algorithm.iteration.map!(styleSample).map!(sparkles.base.term_style.Style[])(sparkles.base.term_style.Style[] r) pure nothrow @nogc @safeImplements the homonym function (also known as transform) present
in many languages of functional flavor. The call ``map!(fun)(range)
returns a range of which elements are obtained by applying fun(a)
left to right for all elements a in range. The original ranges are
not changed. Evaluation is done lazily.
Examples
import std.algorithm.comparison : equal;
import std.range : chain, only;
auto squares =
chain(only(1, 2, 3, 4), only(5, 6)).map!(a => a * a);
assert(equal(squares, only(1, 4, 9, 16, 25, 36)));
Multiple functions can be passed to map. In that case, the
element type of map is a tuple containing one element for each
function.
auto sums = [2, 4, 6, 8];
auto products = [1, 4, 9, 16];
size_t i = 0;
foreach (result; [ 1, 2, 3, 4 ].map!("a + a", "a * a"))
{
assert(result[0] == sums[i]);
assert(result[1] == products[i]);
++i;
}
You may alias map with some function(s) to a symbol and use
it separately:
import std.algorithm.comparison : equal;
import std.conv : to;
alias stringize = map!(to!string);
assert(equal(stringize([ 1, 2, 3, 4 ]), [ "1", "2", "3", "4" ]));
map!string sparkles.base.term_style.styleSample(sparkles.base.term_style.Style style, bool resetAfter = true) pure nothrow @safeReturns the name of a Style styled with that style.
Useful for displaying style palettes where styles demonstrate themselves.
Example
``styleSample(Style.red) returns "red" rendered in red.
Examples
assert(styleSample(Style.red) == "\x1b[31mred\x1b[39m");
assert(styleSample(Style.bold) == "\x1b[1mbold\x1b[22m");
assert(styleSample(Style.green, false) == "\x1b[32mgreen");
styleSample.std.algorithm.iteration.joiner!(MapResult!(styleSample, Style[]), string).Result std.algorithm.iteration.joiner!(std.algorithm.iteration.MapResult!(styleSample, Style[]), string)(std.algorithm.iteration.MapResult!(styleSample, Style[]) r, string sep) pure nothrow @safeLazily joins a range of ranges with a separator. The separator itself
is a range. If a separator is not provided, then the ranges are
joined directly without anything in between them (often called flatten
in other languages).
Note
When both outer and inner ranges of RoR are bidirectional and the joiner is
iterated from the back to the front, the separator will still be consumed from
front to back, even if it is a bidirectional range too.
Examples
import std.algorithm.comparison : equal;
import std.conv : text;
assert(["abc", "def"].joiner.equal("abcdef"));
assert(["Mary", "has", "a", "little", "lamb"]
.joiner("...")
.equal("Mary...has...a...little...lamb"));
assert(["", "abc"].joiner("xyz").equal("xyzabc"));
assert([""].joiner("xyz").equal(""));
assert(["", ""].joiner("xyz").equal("xyz"));
joiner(" ").string std.conv.to!string.to!(std.algorithm.iteration.joiner!(MapResult!(styleSample, Style[]), string).Result)(std.algorithm.iteration.joiner!(MapResult!(styleSample, Style[]), string).Result __param_0) pure @safeThe to template converts a value from one type to another.
The source type is deduced and the target type must be specified, for example the
expression to`!int(42.0)` converts the number 42 from
`double` to `int`. The conversion is "safe", i.e.,
it checks for overflow; to!int(4.2e10) would throw the
ConvOverflowException exception. Overflow checks are only
inserted when necessary, e.g., ``to!double(42) does not do
any checking because any int fits in a double.
Conversions from string to numeric types differ from the C equivalents
atoi() and atol() by checking for overflow and not allowing whitespace.
For conversion of strings to signed types, the grammar recognized is:
Integer:
Sign UnsignedInteger
UnsignedInteger
Sign:
+
-
For conversion to unsigned types, the grammar recognized is:
UnsignedInteger:
DecimalDigit
DecimalDigit UnsignedInteger
Examples
Converting a value to its own type (useful mostly for generic code)
simply returns its argument.
int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14
Converting among numeric types is a safe way to cast them around.
Conversions from floating-point types to integral types allow loss of
precision (the fractional part of a floating-point number). The
conversion is truncating towards zero, the same way a cast would
truncate. (To round a floating point value when casting to an
integral, use roundTo.)
import std.exception : assertThrown;
int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));
assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);
When converting strings to numeric types, note that D hexadecimal and binary
literals are not handled. Neither the prefixes that indicate the base, nor the
horizontal bar used to separate groups of digits are recognized. This also
applies to the suffixes that indicate the type.
To work around this, you can specify a radix for conversions involving numbers.
auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);
Conversions from integral types to floating-point types always
succeed, but might lose accuracy. The largest integers with a
predecessor representable in floating-point format are 2^24-1 for
float, 2^53-1 for double, and 2^64-1 for real (when
real is 80-bit, e.g. on Intel machines).
// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);
Conversion from string types to char types enforces the input
to consist of a single code point, and said code point must
fit in the target type. Otherwise, ConvException is thrown.
import std.exception : assertThrown;
assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');
// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');
// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));
Converting an array to another array type works by converting each
element in turn. Associative arrays can be converted to associative
arrays as long as keys and values can in turn be converted.
import std.string : split;
int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);
Conversions operate transitively, meaning that they work on arrays and
associative arrays of any complexity.
This conversion works because to`!short` applies to an `int`, to!wstring
applies to a string, to`!string` applies to a `double`, and
to!(double[]) applies to an int[]. The conversion might throw an
exception because ``to!short might fail the range check.
int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);
Object-to-object conversions by dynamic casting throw exception when
the source is non-null and the target is null.
import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));
Stringize conversion from all types is supported.
String to string conversion works for any two string types having
(char, wchar, dchar) character widths and any
combination of qualifiers (mutable, const, or immutable).
Converts array (other than strings) to string.
Each element is converted by calling ``to!T.
Associative array to string conversion.
Each element is converted by calling ``to!T.
Object to string conversion calls toString against the object or
returns "null" if the object is null.
Struct to string conversion calls toString against the struct if
it is defined.
For structs that do not define toString, the conversion to string
produces the list of fields.
Enumerated types are converted to strings as their symbolic names.
Boolean values are converted to "true" or "false".
char, wchar, dchar to a string type.
Unsigned or signed integers to strings.
: Convert integral value to string in radix radix.
radix must be a value from 2 to 36.
value is treated as a signed value only if radix is 10.
The characters A through Z are used to represent values 10 through 36
and their case is determined by the letterCase parameter.
All floating point types to all string types.
Pointer to string conversions convert the pointer to a size_t value.
If pointer is char*, treat it as C-style strings.
In that case, this function is @system.
See formatValue on how toString should be defined.
// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");
// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
to!string(associativeArray) == `["1":2, "0":1]`);
// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");
// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);
auto c = to!(wchar[])(b);
assert(c == "abcx");
Strings can be converted to enum types. The enum member with the same name as the
input string is returned. The comparison is case-sensitive.
A ConvException is thrown if the enum does not have the specified member.
import std.exception : assertThrown;
enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to!(alias) object.string = stringstring,
].string sparkles.ui.components.box.drawBox(string[] content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))drawBox("Styles"),
),
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "Complex Data Structure",
content: (struct) box.ClusterCluster(
name: "Production",
servers: [
(struct) box.ServerServer("web-01", "192.168.1.10", 80),
(struct) box.ServerServer("web-02", "192.168.1.11", 80),
(struct) box.ServerServer("db-01", "192.168.1.20", 5432),
],
active: true,
).string sparkles.base.prettyprint.prettyPrint!(box.Cluster, void)(in box.Cluster value, in sparkles.base.prettyprint.PrettyPrintOptions!void opt = PrettyPrintOptions(cast(ushort)2u, cast(ushort)8u, 32u, 80u, true, false)) pure nothrow @safeConvenience overload that returns a string.
prettyPrint((template instance) sparkles.base.prettyprint.PrettyPrintOptions!voidPrettyPrintOptions!void(softMaxWidth: 60)).string sparkles.ui.components.box.drawBox(string content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))Overload that accepts a single string and splits it into lines internally.
drawBox("Cluster"),
),
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "Box with Footer",
content: [
"Build started at 14:32:01",
"Compiling 42 modules...",
"Linking executable...",
"Build completed in 3.2s",
].string sparkles.ui.components.box.drawBox(string[] content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))drawBox("Build Log", (struct) sparkles.ui.components.box.BoxPropsBoxProps(footer: string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x93 Success}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x93 Success}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{green ✓ Success}"))),
),
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "Task Status with Footer",
content: [
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Task: }Deploy to production")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Task: }Deploy to production" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{bold Task: }Deploy to production"),
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Started: }2024-01-15 10:30")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Started: }2024-01-15 10:30" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{bold Started: }2024-01-15 10:30"),
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Duration: }45 seconds")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Duration: }45 seconds" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{bold Duration: }45 seconds"),
].string sparkles.ui.components.box.drawBox(string[] content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))drawBox(
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{cyan deploy-v2.1.0}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{cyan deploy-v2.1.0}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{cyan deploy-v2.1.0}"),
(struct) sparkles.ui.components.box.BoxPropsBoxProps(footer: string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{red \xe2\x9c\x97 Failed}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{red \xe2\x9c\x97 Failed}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{red ✗ Failed}")),
),
),
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "minWidth - Pad a Short Box to a Fixed Frame",
content: ["Done"]
.string sparkles.ui.components.box.drawBox(string[] content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))drawBox("Status", (struct) sparkles.ui.components.box.BoxPropsBoxProps(minWidth: 40)),
),
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "maxWidth - Wrap Long Lines Within the Frame",
content: [
"The quick brown fox jumps over the lazy dog and keeps on running well past the edge.",
].string sparkles.ui.components.box.drawBox(string[] content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))drawBox("Wrapped", (struct) sparkles.ui.components.box.BoxPropsBoxProps(maxWidth: 40)),
),
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "Fixed Width - minWidth == maxWidth",
content: [
"Short line",
"A much longer line that has to wrap to stay inside the fixed-width frame.",
].string sparkles.ui.components.box.drawBox(string[] content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))drawBox(
"Fixed 40",
(struct) sparkles.ui.components.box.BoxPropsBoxProps(minWidth: 40, maxWidth: 40, footer: string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x93 aligned}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x93 aligned}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safeditto — defaults to ColorDepth.trueColor (no folding).
styledText(i"{green ✓ aligned}")),
),
),
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "Aligned Stack - Same Width Regardless of Content",
content: [
["ok"].string sparkles.ui.components.box.drawBox(string[] content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))drawBox("alpha", (struct) sparkles.ui.components.box.BoxPropsBoxProps(minWidth: 44, maxWidth: 44)),
["a slightly longer middle line"]
.string sparkles.ui.components.box.drawBox(string[] content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))drawBox("beta", (struct) sparkles.ui.components.box.BoxPropsBoxProps(minWidth: 44, maxWidth: 44)),
["x"].string sparkles.ui.components.box.drawBox(string[] content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))drawBox("gamma", (struct) sparkles.ui.components.box.BoxPropsBoxProps(minWidth: 44, maxWidth: 44)),
].std.algorithm.iteration.joiner!(string[], string).Result std.algorithm.iteration.joiner!(string[], string)(string[] r, string sep) pure nothrow @nogc @safeLazily joins a range of ranges with a separator. The separator itself
is a range. If a separator is not provided, then the ranges are
joined directly without anything in between them (often called flatten
in other languages).
Note
When both outer and inner ranges of RoR are bidirectional and the joiner is
iterated from the back to the front, the separator will still be consumed from
front to back, even if it is a bidirectional range too.
Examples
import std.algorithm.comparison : equal;
import std.conv : text;
assert(["abc", "def"].joiner.equal("abcdef"));
assert(["Mary", "has", "a", "little", "lamb"]
.joiner("...")
.equal("Mary...has...a...little...lamb"));
assert(["", "abc"].joiner("xyz").equal("xyzabc"));
assert([""].joiner("xyz").equal(""));
assert(["", ""].joiner("xyz").equal("xyz"));
joiner("\n").string std.conv.to!string.to!(std.algorithm.iteration.joiner!(string[], string).Result)(std.algorithm.iteration.joiner!(string[], string).Result __param_0) pure @safeThe to template converts a value from one type to another.
The source type is deduced and the target type must be specified, for example the
expression to`!int(42.0)` converts the number 42 from
`double` to `int`. The conversion is "safe", i.e.,
it checks for overflow; to!int(4.2e10) would throw the
ConvOverflowException exception. Overflow checks are only
inserted when necessary, e.g., ``to!double(42) does not do
any checking because any int fits in a double.
Conversions from string to numeric types differ from the C equivalents
atoi() and atol() by checking for overflow and not allowing whitespace.
For conversion of strings to signed types, the grammar recognized is:
Integer:
Sign UnsignedInteger
UnsignedInteger
Sign:
+
-
For conversion to unsigned types, the grammar recognized is:
UnsignedInteger:
DecimalDigit
DecimalDigit UnsignedInteger
Examples
Converting a value to its own type (useful mostly for generic code)
simply returns its argument.
int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14
Converting among numeric types is a safe way to cast them around.
Conversions from floating-point types to integral types allow loss of
precision (the fractional part of a floating-point number). The
conversion is truncating towards zero, the same way a cast would
truncate. (To round a floating point value when casting to an
integral, use roundTo.)
import std.exception : assertThrown;
int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));
assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);
When converting strings to numeric types, note that D hexadecimal and binary
literals are not handled. Neither the prefixes that indicate the base, nor the
horizontal bar used to separate groups of digits are recognized. This also
applies to the suffixes that indicate the type.
To work around this, you can specify a radix for conversions involving numbers.
auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);
Conversions from integral types to floating-point types always
succeed, but might lose accuracy. The largest integers with a
predecessor representable in floating-point format are 2^24-1 for
float, 2^53-1 for double, and 2^64-1 for real (when
real is 80-bit, e.g. on Intel machines).
// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);
Conversion from string types to char types enforces the input
to consist of a single code point, and said code point must
fit in the target type. Otherwise, ConvException is thrown.
import std.exception : assertThrown;
assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');
// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');
// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));
Converting an array to another array type works by converting each
element in turn. Associative arrays can be converted to associative
arrays as long as keys and values can in turn be converted.
import std.string : split;
int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);
Conversions operate transitively, meaning that they work on arrays and
associative arrays of any complexity.
This conversion works because to`!short` applies to an `int`, to!wstring
applies to a string, to`!string` applies to a `double`, and
to!(double[]) applies to an int[]. The conversion might throw an
exception because ``to!short might fail the range check.
int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);
Object-to-object conversions by dynamic casting throw exception when
the source is non-null and the target is null.
import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));
Stringize conversion from all types is supported.
String to string conversion works for any two string types having
(char, wchar, dchar) character widths and any
combination of qualifiers (mutable, const, or immutable).
Converts array (other than strings) to string.
Each element is converted by calling ``to!T.
Associative array to string conversion.
Each element is converted by calling ``to!T.
Object to string conversion calls toString against the object or
returns "null" if the object is null.
Struct to string conversion calls toString against the struct if
it is defined.
For structs that do not define toString, the conversion to string
produces the list of fields.
Enumerated types are converted to strings as their symbolic names.
Boolean values are converted to "true" or "false".
char, wchar, dchar to a string type.
Unsigned or signed integers to strings.
: Convert integral value to string in radix radix.
radix must be a value from 2 to 36.
value is treated as a signed value only if radix is 10.
The characters A through Z are used to represent values 10 through 36
and their case is determined by the letterCase parameter.
All floating point types to all string types.
Pointer to string conversions convert the pointer to a size_t value.
If pointer is char*, treat it as C-style strings.
In that case, this function is @system.
See formatValue on how toString should be defined.
// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");
// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
to!string(associativeArray) == `["1":2, "0":1]`);
// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");
// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);
auto c = to!(wchar[])(b);
assert(c == "abcx");
Strings can be converted to enum types. The enum member with the same name as the
input string is returned. The comparison is case-sensitive.
A ConvException is thrown if the enum does not have the specified member.
import std.exception : assertThrown;
enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to!(alias) object.string = stringstring,
),
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "Title Overflow - wrap (nested title box with ┤ ├ handles)",
content: [
"Body content line one",
"Body content line two",
].string sparkles.ui.components.box.drawBox(string[] content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))drawBox(
"This is a very long multi-line drawBox title. It ends here.",
(struct) sparkles.ui.components.box.BoxPropsBoxProps(maxWidth: 40, titleOverflow: (enum) sparkles.ui.components.box.TitleOverflowHow a title too wide for maxWidth is handled. Only takes effect when
maxWidth > 0; with no cap the box always expands to fit the title.
TitleOverflow.(enum value) sparkles.ui.components.box.TitleOverflow.wrap = 1Wrap a long title into a nested title box (┤ ├ handles on the frame).
wrap),
),
),
(struct) sparkles.ui.components.demo.SectionA section in a demo with a header and content.
Section(
header: "Title Overflow - ellipsis (truncate to one line)",
content: ["Body content line one"]
.string sparkles.ui.components.box.drawBox(string[] content, string title, sparkles.ui.components.box.BoxProps props = BoxProps(false, null, null, null, null, null, 0LU, 0LU, TitleOverflow.expand, '\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u257c', '\u257e', '\u2524', '\u251c'))drawBox(
"This is a very long multi-line drawBox title. It ends here.",
(struct) sparkles.ui.components.box.BoxPropsBoxProps(maxWidth: 40, titleOverflow: (enum) sparkles.ui.components.box.TitleOverflowHow a title too wide for maxWidth is handled. Only takes effect when
maxWidth > 0; with no cap the box always expands to fit the title.
TitleOverflow.(enum value) sparkles.ui.components.box.TitleOverflow.ellipsis = 2Truncate the title to one line with a trailing '…'.
ellipsis),
),
),
],
);
}