Skip to content

Commit

Permalink
Opened LineBuilder for 3rd party handlers
Browse files Browse the repository at this point in the history
public ctor & Default NewLine value changed to Environment.NewLine (platform dependent)

Also RemoveNewLine() renamed as RemoveLastNewLine()
  • Loading branch information
3F committed Apr 3, 2024
1 parent e8805a8 commit 1abff30
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 18 deletions.
78 changes: 73 additions & 5 deletions MvsSln/Core/LineBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ public sealed class LineBuilder

private string newline;

/// <summary>
/// Tab character or equivalent used in the current instance in related operations.
/// </summary>
public string Tab
{
get => tab;
Expand All @@ -30,6 +33,10 @@ public string Tab
}
}

/// <summary>
/// EOL character (or a sequence of characters) used for newline operations in the current instance.
/// </summary>
/// <remarks>null as set value causes the value to be set using <see cref="Environment.NewLine"/></remarks>
public string NewLine
{
get => newline;
Expand All @@ -38,27 +45,67 @@ public string NewLine

public int Length => sb.Length;

/// <summary>
/// Adds string value to the current character set.
/// </summary>
/// <param name="value">String value to be added to the current character set.</param>
/// <returns>Self reference to continue the chain.</returns>
/// <exception cref="ArgumentNullException"></exception>
public LineBuilder Append(string value)
{
sb.Append(value ?? throw new ArgumentNullException(nameof(value)));
return this;
}

/// <summary>
/// Adds string value together with <see cref="NewLine"/> to the current character set.
/// </summary>
/// <inheritdoc cref="Append(string)"/>
public LineBuilder AppendLine(string value) => Append(value).Append(newline);

/// <summary>
/// Adds <see cref="NewLine"/> to the current character set.
/// </summary>
/// <returns>Self reference to continue the chain.</returns>
public LineBuilder AppendLine() => Append(newline);

/// <summary>
/// <see cref="Append(string)"/> using first level indentation.
/// </summary>
/// <inheritdoc cref="Append(string)"/>
public LineBuilder AppendLv1(string value) => Append(tab).Append(value);

/// <summary>
/// <see cref="Append(string)"/> using second level indentation.
/// </summary>
/// <inheritdoc cref="AppendLv1(string)"/>
public LineBuilder AppendLv2(string value) => Append(doubleTab).Append(value);

/// <summary>
/// <see cref="AppendLine(string)"/> using first level indentation.
/// </summary>
/// <inheritdoc cref="AppendLv1(string)"/>
public LineBuilder AppendLv1Line(string value) => AppendLv1(value).AppendLine();

/// <summary>
/// <see cref="AppendLine(string)"/> using second level indentation.
/// </summary>
/// <inheritdoc cref="AppendLv1Line(string)"/>
public LineBuilder AppendLv2Line(string value) => AppendLv2(value).AppendLine();

public LineBuilder RemoveNewLine()
/// <summary>
/// Remove the last <see cref="NewLine"/> from the current instance if present.
/// </summary>
/// <returns>Self reference to continue the chain.</returns>
public LineBuilder RemoveLastNewLine()
=> ContainsLast(newline) ? RemoveLast(newline.Length) : this;

/// <summary>
/// Remove the last characters from the current instance.
/// </summary>
/// <param name="length">Number of characters being removed.</param>
/// <returns>Self reference to continue the chain.</returns>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public LineBuilder RemoveLast(int length)
{
if(length < 0 || length > sb.Length)
Expand All @@ -69,39 +116,60 @@ public LineBuilder RemoveLast(int length)
return Remove(sb.Length - length, length);
}

/// <inheritdoc cref="StringBuilder.Remove(int, int)"/>
public LineBuilder Remove(int startIndex, int length)
{
sb.Remove(startIndex, length);
return this;
}

/// <summary>
/// Removes all characters from the current instance.
/// </summary>
/// <inheritdoc cref="AppendLine()"/>
public LineBuilder Clear()
{
sb.Clear();
return this;
}

/// <summary>
/// Checks whether there is a sequence from the passed value at the end.
/// </summary>
/// <param name="value"></param>
/// <returns>true if the value being tested is at the end of the sequence of the current instance.</returns>
/// <exception cref="ArgumentNullException"></exception>
public bool ContainsLast(string value)
{
if(value == null) throw new ArgumentNullException(nameof(value));
if(sb.Length < value.Length || value == string.Empty) return false;
return value == ToString(sb.Length - value.Length, value.Length);
}

public string ToString(bool removeNewLine)
/// <param name="noLastNewLine">If true, remove <see cref="NewLine"/> at the end of the resulting string if present.</param>
/// <inheritdoc cref="ToString()"/>
public string ToString(bool noLastNewLine)
{
if(!removeNewLine) return sb.ToString();
if(!noLastNewLine) return sb.ToString();

return ContainsLast(newline) ? sb.ToString(0, sb.Length - newline.Length) : sb.ToString();
}

/// <inheritdoc cref="StringBuilder.ToString(int, int)"/>
public string ToString(int startIndex, int length) => sb.ToString(startIndex, length);

/// <inheritdoc cref="StringBuilder.ToString()"/>
public override string ToString() => sb.ToString();

internal LineBuilder(string newline = "\r\n", string tab = "\t")
public LineBuilder()
: this(newline: null)
{
Tab = tab ?? throw new ArgumentNullException(nameof(tab));

}

public LineBuilder(string newline, string tab = "\t")
{
Tab = tab;
NewLine = newline;

sb = new StringBuilder();
Expand Down
2 changes: 1 addition & 1 deletion MvsSln/Core/ObjHandlers/WProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public override string Extract(object data)
lbuilder.AppendLine(EndProject);
}

return lbuilder.ToString(removeNewLine: true);
return lbuilder.ToString(noLastNewLine: true);
}

/// <param name="pItems">List of projects in solution.</param>
Expand Down
2 changes: 1 addition & 1 deletion MvsSln/Core/ObjHandlers/WProjectSolutionItems.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public override string Extract(object data)
lbuilder.AppendLv1Line(EndProjectSection).AppendLine(EndProject);
}

return lbuilder.ToString(removeNewLine: true);
return lbuilder.ToString(noLastNewLine: true);
}

/// <param name="folders">List of solution folders.</param>
Expand Down
2 changes: 1 addition & 1 deletion MvsSln/Core/ObjHandlers/WVisualStudioVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public override string Extract(object data)
lbuilder.AppendLine($"{MinimumVisualStudioVersion} = {header.MinimumVisualStudioVersion}");
}

return lbuilder.ToString(removeNewLine: true);
return lbuilder.ToString(noLastNewLine: true);
}
}
}
29 changes: 20 additions & 9 deletions MvsSlnTest/Core/LineBuilderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ public void BuilderTest1(string nl, string tab)
Assert.Equal(tab, lb.Tab);
Assert.Equal(nl, lb.NewLine);

Assert.Equal(exp, lb.ToString(removeNewLine: true));
Assert.Equal($"{exp}{nl}", lb.ToString(removeNewLine: false));
Assert.Equal(exp, lb.ToString(noLastNewLine: true));
Assert.Equal($"{exp}{nl}", lb.ToString(noLastNewLine: false));
Assert.Equal($"{exp}{nl}", lb.ToString());

lb.RemoveNewLine();
lb.RemoveLastNewLine();
Assert.Equal(exp, lb.ToString());

lb.Clear();
Expand Down Expand Up @@ -64,11 +64,11 @@ public void BuilderTest2(string nl, string tab)
Assert.Equal(tab, lb.Tab);
Assert.Equal(nl, lb.NewLine);

Assert.Equal(exp, lb.ToString(removeNewLine: true));
Assert.Equal(exp, lb.ToString(removeNewLine: false));
Assert.Equal(exp, lb.ToString(noLastNewLine: true));
Assert.Equal(exp, lb.ToString(noLastNewLine: false));
Assert.Equal(exp, lb.ToString());

lb.RemoveNewLine();
lb.RemoveLastNewLine();
Assert.Equal(exp, lb.ToString());

lb.Clear();
Expand All @@ -95,6 +95,17 @@ public void CtorTest1(string nl, string tab)
}
#endif

[Fact]
public void CtorTest2()
{
LineBuilder lb = new();
lb.AppendLine("1").AppendLine("2").AppendLine("3")
.RemoveLastNewLine();

string nl = Environment.NewLine;
Assert.Equal($"1{nl}2{nl}3", lb.ToString());
}

[Fact]
public void ContainsLastTest1()
{
Expand Down Expand Up @@ -137,16 +148,16 @@ public void ToStringTest1()
{
LineBuilder lb = new();

Assert.Equal(string.Empty, lb.ToString(removeNewLine: true));
Assert.Equal(string.Empty, lb.ToString(noLastNewLine: true));
Assert.Equal(0, lb.Length);

string wrd = "Hello";
lb.AppendLine(wrd);
Assert.Equal(wrd.Length + lb.NewLine.Length, lb.Length);
Assert.Equal(wrd, lb.ToString(removeNewLine: true));
Assert.Equal(wrd, lb.ToString(noLastNewLine: true));
Assert.Equal(wrd.Length + lb.NewLine.Length, lb.Length);

lb.RemoveNewLine();
lb.RemoveLastNewLine();
Assert.Equal(wrd.Length, lb.Length);
}

Expand Down
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ We're waiting for your awesome contributions!
| Releases | Windows | Linux
|-------------|---------|--------
| [📦 ![NuGet](https://img.shields.io/nuget/v/MvsSln.svg)](https://www.nuget.org/packages/MvsSln/) | [![status](https://ci.appveyor.com/api/projects/status/6uunsds889rhkpo2/branch/master?svg=true)](https://ci.appveyor.com/project/3Fs/mvssln-fxjnf/branch/master) | [![status](https://ci.appveyor.com/api/projects/status/vdt3taxswrxo37tt/branch/master?svg=true)](https://ci.appveyor.com/project/3Fs/mvssln-2d2c2/branch/master)
| [![release](https://img.shields.io/github/release/3F/MvsSln.svg)](https://github.com/3F/MvsSln/releases/latest) | [![Tests](https://img.shields.io/appveyor/tests/3Fs/mvssln-fxjnf/master.svg)](https://ci.appveyor.com/project/3Fs/mvssln-fxjnf/build/tests)
| [![release](https://img.shields.io/github/release/3F/MvsSln.svg)](https://github.com/3F/MvsSln/releases/latest) | [![Tests](https://img.shields.io/appveyor/tests/3Fs/mvssln-fxjnf/master.svg)](https://ci.appveyor.com/project/3Fs/mvssln-fxjnf/build/tests) | [![Tests](https://img.shields.io/appveyor/tests/3Fs/mvssln-2d2c2/master.svg)](https://ci.appveyor.com/project/3Fs/mvssln-2d2c2/build/tests)

</td><td>

Expand Down

0 comments on commit 1abff30

Please sign in to comment.