-
Notifications
You must be signed in to change notification settings - Fork 8
feat: Porting PadLeft and PadRight from C# #46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
d27fbe9
7212e8f
9e6f685
5e09f08
8a5d7d9
9449659
202a82d
f806902
7855fc1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -758,3 +758,141 @@ public static string Exec(string src, string remove, string insert) | |
| return src.Replace(remove, insert); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Functions to add padding to either end of a string. | ||
| /// The center version (PadCenter) will add spaces to both ends of the given string. | ||
| /// The start version (PadStart) will add spaces to the start of the given string. | ||
| /// The end version (PadEnd) will add spaces to the end of the given string. | ||
| /// </summary> | ||
gavinbm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| public sealed partial class TextPadFunc : RexlOper | ||
| { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As suggested elsewhere:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also register |
||
| public enum PadKind : byte | ||
| { | ||
| // Center justification, pad both ends of the string | ||
| Center, | ||
| // Pad the start of the string. | ||
| Start, | ||
| // Pad the end of the string. | ||
| End | ||
| } | ||
|
|
||
| public static readonly TextPadFunc PadCenter = new TextPadFunc(PadKind.Center, "Pad"); | ||
| public static readonly TextPadFunc PadStart = new TextPadFunc(PadKind.Start, "PadStart"); | ||
| public static readonly TextPadFunc PadEnd = new TextPadFunc(PadKind.End, "PadEnd"); | ||
|
|
||
| public PadKind Kind { get; } | ||
|
|
||
| public Func<string, long, string> Map { get; } | ||
|
|
||
| private TextPadFunc(PadKind kind, string name) | ||
| : base(isFunc: true, new DName(name), BindUtil.TextNs, 2, 2) | ||
| { | ||
| switch (kind) | ||
| { | ||
| case PadKind.Start: | ||
| Map = ExecStart; | ||
| break; | ||
| case PadKind.End: | ||
| Map = ExecEnd; | ||
| break; | ||
| default: | ||
| Validation.Assert(kind == PadKind.Center); | ||
| Map = ExecCenter; | ||
| break; | ||
| } | ||
|
|
||
| Kind = kind; | ||
| } | ||
|
|
||
| protected override ArgTraits GetArgTraitsCore(int carg) | ||
| { | ||
| Validation.Assert(SupportsArity(carg)); | ||
| var maskAll = BitSet.GetMask(carg); | ||
| var maskOpt = maskAll.ClearBit(0); | ||
| return ArgTraitsLifting.Create(this, carg, maskLiftSeq: maskAll, maskLiftTen: maskAll, maskLiftOpt: maskOpt); | ||
| } | ||
|
|
||
| protected override (DType, Immutable.Array<DType>) SpecializeTypesCore(InvocationInfo info) | ||
| { | ||
| Validation.AssertValue(info); | ||
| Validation.Assert(SupportsArity(info.Arity)); | ||
| Validation.Assert(info.Arity == 2); | ||
|
|
||
| return (DType.Text, Immutable.Array.Create(DType.Text, DType.I8Req)); | ||
| } | ||
|
|
||
| protected override bool CertifyCore(BndCallNode call, ref bool full) | ||
| { | ||
| if (call.Type != DType.Text) | ||
| return false; | ||
| var args = call.Args; | ||
| if (args[0].Type != DType.Text) | ||
| return false; | ||
| if (args[1].Type != DType.I8Req) | ||
| return false; | ||
| return true; | ||
| } | ||
|
|
||
shonk-msft marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| protected override BoundNode ReduceCore(IReducer reducer, BndCallNode call) | ||
| { | ||
| Validation.AssertValue(reducer); | ||
| Validation.Assert(IsValidCall(call)); | ||
|
|
||
| var lenArg = call.Args[1]; | ||
| if (lenArg.TryGetI8(out var len)) | ||
| { | ||
| var srcArg = call.Args[0]; | ||
| if (len <= 0) | ||
| return srcArg; | ||
| if (srcArg.TryGetString(out var str)) | ||
| { | ||
| if (Util.Size(str) >= len) | ||
| return srcArg; | ||
| return BndStrNode.Create(Map(str, len)); | ||
| } | ||
| } | ||
|
|
||
| return call; | ||
| } | ||
|
|
||
| public static string ExecCenter(string src, long len) | ||
| { | ||
| if (len <= 0) | ||
| return src; | ||
| int count = (int)Math.Min(len, int.MaxValue); | ||
| if (string.IsNullOrEmpty(src)) | ||
| return new string(' ', count); | ||
| if (count <= src.Length) | ||
| return src; | ||
| return string.Create(count, src.AsMemory(), static (dst, mem) => | ||
| { | ||
| int spaces = (dst.Length - mem.Length) / 2; | ||
|
|
||
| if (spaces > 0) | ||
| dst.Slice(0, spaces).Fill(' '); | ||
| mem.Span.CopyTo(dst.Slice(spaces, mem.Length)); | ||
| dst.Slice(spaces + mem.Length).Fill(' '); | ||
| }); | ||
| } | ||
|
|
||
| public static string ExecStart(string src, long len) | ||
| { | ||
| if (len <= 0) | ||
| return src; | ||
| int count = (int)Math.Min(len, int.MaxValue); | ||
| if (string.IsNullOrEmpty(src)) | ||
| return new string(' ', count); | ||
| return src.PadLeft(count); | ||
| } | ||
|
|
||
| public static string ExecEnd(string src, long len) | ||
| { | ||
| if (len <= 0) | ||
| return src; | ||
| int count = (int)Math.Min(len, int.MaxValue); | ||
| if (string.IsNullOrEmpty(src)) | ||
| return new string(' ', count); | ||
| return src.PadRight(count); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -238,6 +238,43 @@ Text.Replace("ABC", "X", s) | |
| Text.Replace("ABC", "B", "X") | ||
| Text.Replace("ABACDAE", "A", "!!") | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There should be multiple kinds of test cases:
|
||
| Text.PadStart(s, i8) | ||
| Text.PadStart(null, 0) | ||
| Text.PadStart("hello", -1) | ||
| Text.PadStart(s, -1) | ||
| Text.PadStart("hello", 10) | ||
| Text.PadStart(s, 10) | ||
| Text.PadStart(s, s) | ||
| Text.PadStart(s, u2) | ||
| Text.PadStart(s, qi8) | ||
| Text.PadStart(s, qu2) | ||
| Text.PadStart(i8, i8) | ||
|
|
||
| Text.PadEnd(s, i8) | ||
| Text.PadEnd(null, 0) | ||
| Text.PadEnd("hello", -1) | ||
| Text.PadEnd(s, -1) | ||
| Text.PadEnd("hello", 10) | ||
| Text.PadEnd(s, 10) | ||
| Text.PadEnd(s, s) | ||
| Text.PadEnd(s, u2) | ||
| Text.PadEnd(s, qi8) | ||
| Text.PadEnd(s, qu2) | ||
| Text.PadEnd(i8, i8) | ||
|
|
||
| Tex.Pad(s, i8) | ||
| Text.PadCenter(s, i8) | ||
| Text.Pad(null, 15) | ||
| Text.Pad("hello", -1) | ||
| Text.Pad(s, -1) | ||
| Text.Pad("hello", 10) | ||
| Text.Pad(s, 10) | ||
| Text.Pad(s, s) | ||
| Text.Pad(s, u2) | ||
| Text.Pad(s, qi8) | ||
| Text.Pad(s, qu2) | ||
| Text.Pad(i8, i8) | ||
|
|
||
| // Lifting. | ||
| :: {g:g*, o:o*, s:s*, b:b*, qb:b?*, d:d*, n:n*, qn:n?*, r8:r8*, qr8:r8?*, r4:r4*, qr4:r4?*, i:i*, qi:i?*, i8:i8*, qi8:i8?*, i4:i4*, qi4:i4?*, i2:i2*, qi2:i2?*, i1:i1*, qi1:i1?*, u8:u8*, qu8:u8?*, u4:u4*, qu4:u4?*, u2:u2*, qu2:u2?*, u1:u1*, qu1:u1?*} | ||
|
|
||
|
|
@@ -360,3 +397,51 @@ Text.Replace("ABC", s, s) | |
| Text.Replace(s, s, s) | ||
|
|
||
| Text.Replace(s, "", s) | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These tests aren't needed since they just duplicate what is above. |
||
| Text.PadStart(s, i8) | ||
| Text.PadStart(null, 0) | ||
| Text.PadStart("hello", -1) | ||
| Text.PadStart("hello", [3, 4, 1]) | ||
| Text.PadStart(s, [3, 4, 1]) | ||
| Text.PadStart(s, -1) | ||
| Text.PadStart("hello", 10) | ||
| Text.PadStart(["hello", "howdy", null], 10) | ||
| Text.PadStart(s, 10) | ||
| Text.PadStart(s, s) | ||
| Text.PadStart(s, u1) | ||
| Text.PadStart(s, u2) | ||
| Text.PadStart(s, u4) | ||
| Text.PadStart(s, u8) | ||
| Text.PadStart(s, qi8) | ||
| Text.PadStart(s, qu2) | ||
|
|
||
| Text.PadEnd(s, i8) | ||
| Text.PadEnd(null, 0) | ||
| Text.PadEnd(s, -1) | ||
| Text.PadEnd(s, [3, 4, 1]) | ||
| Text.PadEnd("hello", [3, 4, 9]) | ||
| Text.PadEnd(["hello", "howdy", null], 10) | ||
| Text.PadEnd(s, 10) | ||
| Text.PadEnd(s, s) | ||
| Text.PadEnd(s, u1) | ||
| Text.PadEnd(s, u2) | ||
| Text.PadEnd(s, u4) | ||
| Text.PadEnd(s, u8) | ||
| Text.PadEnd(s, qi8) | ||
| Text.PadEnd(s, qu2) | ||
|
|
||
| Text.PadCenter(s, i8) | ||
| Text.PadCenter(null, 0) | ||
| Text.PadCenter("hello", -1) | ||
| Text.PadCenter("hello", [3, 4, 9]) | ||
| Text.PadCenter(s, -1) | ||
| Text.PadCenter(s, [3, 4, 1]) | ||
| Text.PadCenter(["hello", "howdy", null], 10) | ||
| Text.PadCenter(s, 10) | ||
| Text.PadCenter(s, s) | ||
| Text.PadCenter(s, u1) | ||
| Text.PadCenter(s, u2) | ||
| Text.PadCenter(s, u4) | ||
| Text.PadCenter(s, u8) | ||
| Text.PadCenter(s, qi8) | ||
| Text.PadCenter(s, qu2) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| ::: {g:g, o:o, s:s, b:b, qb:b?, d:d, qd:d?, n:n, qn:n?, r8:r8, qr8:r8?, r4:r4, qr4:r4?, i:i, qi:i?, i8:i8, qi8:i8?, i4:i4, qi4:i4?, i2:i2, qi2:i2?, i1:i1, qi1:i1?, u8:u8, qu8:u8?, u4:u4, qu4:u4?, u2:u2, qu2:u2?, u1:u1, qu1:u1?} | ||
|
|
||
| ``` N := First([null, "hello"]); | ||
| ``` N := Null("hello"); | ||
|
|
||
| Text.Part(Wrap(""), 0) | ||
| Text.Part(Wrap(""), 1) | ||
|
|
@@ -71,3 +71,20 @@ Text.TrimEnd(Wrap(Null(""))) | With(_, {S: it, L: Text.Len(it)}) | |
| Text.Replace(N, "A", "B") | ||
| Text.Replace("A", N, "B") | ||
| Text.Replace("ABC", Wrap("B"), N) | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should also have:
|
||
| Text.PadStart(N, 0) | ||
| Text.PadStart(N, Wrap(10)) | ||
| Text.PadStart("hello", Wrap(-1)) | ||
| Text.PadStart("hello", Wrap(10)) | ||
|
|
||
| Text.PadEnd(N, 0) | ||
| Text.PadEnd(N, Wrap(10)) | ||
| Text.PadEnd("hello", -1) | ||
| Text.PadEnd("hello", 10) | ||
| Text.PadEnd(Wrap("hello"), 10) | ||
|
|
||
| Text.Pad(N, 0) | ||
| Text.Pad(N, Wrap(10)) | ||
| Text.PadCenter("hello", -1) | ||
| Text.Pad("hello", 10) | ||
| Text.Pad(Wrap("hello"), 10) | ||
Uh oh!
There was an error while loading. Please reload this page.