• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

loresoft / FluentCommand / 6497765030

12 Oct 2023 03:22PM UTC coverage: 51.463% (+0.5%) from 50.964%
6497765030

push

github

web-flow
Merge pull request #306 from loresoft/feature/services

Feature/services

979 of 2448 branches covered (0.0%)

Branch coverage included in aggregate %.

213 of 213 new or added lines in 8 files covered. (100.0%)

2890 of 5070 relevant lines covered (57.0%)

156.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

36.63
/src/FluentCommand.Generators/IndentedStringBuilder.cs
1
using System.Text;
2

3
namespace FluentCommand.Generators;
4

5
/// <summary>
6
/// A thin wrapper over <see cref="StringBuilder" /> that adds indentation to each line built.
7
/// </summary>
8
public class IndentedStringBuilder
9
{
10
    private const byte IndentSize = 4;
11
    private byte _indent;
12
    private bool _indentPending = true;
1✔
13

14
    private readonly StringBuilder _stringBuilder = new();
1✔
15

16
    /// <summary>
17
    /// The current length of the built string.
18
    /// </summary>
19
    public virtual int Length
20
        => _stringBuilder.Length;
×
21

22
    /// <summary>
23
    /// Appends the current indent and then the given string to the string being built.
24
    /// </summary>
25
    /// <param name="value">The string to append.</param>
26
    /// <returns>This builder so that additional calls can be chained.</returns>
27
    public virtual IndentedStringBuilder Append(string value)
28
    {
29
        DoIndent();
212✔
30

31
        _stringBuilder.Append(value);
212✔
32

33
        return this;
212✔
34
    }
35

36
    /// <summary>
37
    /// Appends the current indent and then the given char to the string being built.
38
    /// </summary>
39
    /// <param name="value">The char to append.</param>
40
    /// <returns>This builder so that additional calls can be chained.</returns>
41
    public virtual IndentedStringBuilder Append(char value)
42
    {
43
        DoIndent();
×
44

45
        _stringBuilder.Append(value);
×
46

47
        return this;
×
48
    }
49

50
    /// <summary>
51
    /// Appends the current indent and then the given strings to the string being built.
52
    /// </summary>
53
    /// <param name="value">The strings to append.</param>
54
    /// <returns>This builder so that additional calls can be chained.</returns>
55
    public virtual IndentedStringBuilder Append(IEnumerable<string> value)
56
    {
57
        DoIndent();
×
58

59
        foreach (var str in value)
×
60
            _stringBuilder.Append(str);
×
61

62
        return this;
×
63
    }
64

65
    /// <summary>
66
    ///     Appends the current indent and then the given chars to the string being built.
67
    /// </summary>
68
    /// <param name="value">The chars to append.</param>
69
    /// <returns>This builder so that additional calls can be chained.</returns>
70
    public virtual IndentedStringBuilder Append(IEnumerable<char> value)
71
    {
72
        DoIndent();
×
73

74
        foreach (var chr in value)
×
75
            _stringBuilder.Append(chr);
×
76

77
        return this;
×
78
    }
79

80
    /// <summary>
81
    ///     Appends a new line to the string being built.
82
    /// </summary>
83
    /// <returns>This builder so that additional calls can be chained.</returns>
84
    public virtual IndentedStringBuilder AppendLine()
85
    {
86
        AppendLine(string.Empty);
12✔
87

88
        return this;
12✔
89
    }
90

91
    /// <summary>
92
    ///     <para>
93
    ///         Appends the current indent, the given string, and a new line to the string being built.
94
    ///     </para>
95
    ///     <para>
96
    ///         If the given string itself contains a new line, the part of the string after that new line will not be indented.
97
    ///     </para>
98
    /// </summary>
99
    /// <param name="value">The string to append.</param>
100
    /// <returns>This builder so that additional calls can be chained.</returns>
101
    public virtual IndentedStringBuilder AppendLine(string value)
102
    {
103
        if (value.Length != 0)
147✔
104
            DoIndent();
135✔
105

106
        _stringBuilder.AppendLine(value);
147✔
107

108
        _indentPending = true;
147✔
109

110
        return this;
147✔
111
    }
112

113
    /// <summary>
114
    ///     Separates the given string into lines, and then appends each line, prefixed
115
    ///     by the current indent and followed by a new line, to the string being built.
116
    /// </summary>
117
    /// <param name="value">The string to append.</param>
118
    /// <param name="skipFinalNewline">If <see langword="true" />, then the terminating new line is not added after the last line.</param>
119
    /// <returns>This builder so that additional calls can be chained.</returns>
120
    public virtual IndentedStringBuilder AppendLines(string value, bool skipFinalNewline = false)
121
    {
122
        using (var reader = new StringReader(value))
×
123
        {
124
            var first = true;
×
125
            string line;
126
            while ((line = reader.ReadLine()) != null)
×
127
            {
128
                if (first)
×
129
                    first = false;
×
130
                else
131
                    AppendLine();
×
132

133
                if (line.Length != 0)
×
134
                    Append(line);
×
135
            }
136
        }
×
137

138
        if (!skipFinalNewline)
×
139
            AppendLine();
×
140

141
        return this;
×
142
    }
143

144
    /// <summary>
145
    /// Appends a copy of the specified string if <paramref name="condition"/> is met.
146
    /// </summary>
147
    /// <param name="text">The string to append.</param>
148
    /// <param name="condition">The condition delegate to evaluate. If condition is null, String.IsNullOrWhiteSpace method will be used.</param>
149
    public IndentedStringBuilder AppendIf(string text, Func<string, bool> condition = null)
150
    {
151
        var c = condition ?? (s => !string.IsNullOrEmpty(s));
5!
152

153
        if (c(text))
5✔
154
            Append(text);
5✔
155

156
        return this;
5✔
157
    }
158

159
    /// <summary>
160
    /// Appends a copy of the specified string if <paramref name="condition"/> is met.
161
    /// </summary>
162
    /// <param name="text">The string to append.</param>
163
    /// <param name="condition">The condition delegate to evaluate. If condition is null, String.IsNullOrWhiteSpace method will be used.</param>
164
    public IndentedStringBuilder AppendIf(string text, bool condition)
165
    {
166
        if (condition)
×
167
            Append(text);
×
168

169
        return this;
×
170
    }
171

172
    /// <summary>
173
    /// Appends a copy of the specified string followed by the default line terminator if <paramref name="condition"/> is met.
174
    /// </summary>
175
    /// <param name="text">The string to append.</param>
176
    /// <param name="condition">The condition delegate to evaluate. If condition is null, String.IsNullOrWhiteSpace method will be used.</param>
177
    public IndentedStringBuilder AppendLineIf(string text, Func<string, bool> condition = null)
178
    {
179
        var c = condition ?? (s => !string.IsNullOrEmpty(s));
×
180

181
        if (c(text))
×
182
            AppendLine(text);
×
183

184
        return this;
×
185
    }
186

187
    /// <summary>
188
    ///     Resets this builder ready to build a new string.
189
    /// </summary>
190
    /// <returns>This builder so that additional calls can be chained.</returns>
191
    public virtual IndentedStringBuilder Clear()
192
    {
193
        _stringBuilder.Clear();
×
194
        _indent = 0;
×
195

196
        return this;
×
197
    }
198

199
    /// <summary>
200
    ///     Increments the indent.
201
    /// </summary>
202
    /// <returns>This builder so that additional calls can be chained.</returns>
203
    public virtual IndentedStringBuilder IncrementIndent()
204
    {
205
        _indent++;
25✔
206

207
        return this;
25✔
208
    }
209

210
    /// <summary>
211
    ///     Decrements the indent.
212
    /// </summary>
213
    /// <returns>This builder so that additional calls can be chained.</returns>
214
    public virtual IndentedStringBuilder DecrementIndent()
215
    {
216
        if (_indent > 0)
25✔
217
            _indent--;
25✔
218

219
        return this;
25✔
220
    }
221

222
    /// <summary>
223
    ///     Creates a scoped indenter that will increment the indent, then decrement it when disposed.
224
    /// </summary>
225
    /// <returns>An indenter.</returns>
226
    public virtual IDisposable Indent()
227
        => new Indenter(this);
×
228

229
    /// <summary>
230
    ///     Temporarily disables all indentation. Restores the original indentation when the returned object is disposed.
231
    /// </summary>
232
    /// <returns>An object that restores the original indentation when disposed.</returns>
233
    public virtual IDisposable SuspendIndent()
234
        => new IndentSuspender(this);
×
235

236
    /// <summary>
237
    ///     Returns the built string.
238
    /// </summary>
239
    /// <returns>The built string.</returns>
240
    public override string ToString()
241
        => _stringBuilder.ToString();
1✔
242

243
    private void DoIndent()
244
    {
245
        if (_indentPending && _indent > 0)
347✔
246
            _stringBuilder.Append(' ', _indent * IndentSize);
130✔
247

248
        _indentPending = false;
347✔
249
    }
347✔
250

251
    private sealed class Indenter : IDisposable
252
    {
253
        private readonly IndentedStringBuilder _stringBuilder;
254

255
        public Indenter(IndentedStringBuilder stringBuilder)
256
        {
257
            _stringBuilder = stringBuilder;
×
258

259
            _stringBuilder.IncrementIndent();
×
260
        }
×
261

262
        public void Dispose()
263
            => _stringBuilder.DecrementIndent();
×
264
    }
265

266
    private sealed class IndentSuspender : IDisposable
267
    {
268
        private readonly IndentedStringBuilder _stringBuilder;
269
        private readonly byte _indent;
270

271
        public IndentSuspender(IndentedStringBuilder stringBuilder)
272
        {
273
            _stringBuilder = stringBuilder;
×
274
            _indent = _stringBuilder._indent;
×
275
            _stringBuilder._indent = 0;
×
276
        }
×
277

278
        public void Dispose()
279
            => _stringBuilder._indent = _indent;
×
280
    }
281
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc