Skip to content

Commit d6b623c

Browse files
committed
feat: padding empty lines before values
1 parent 577aa5c commit d6b623c

File tree

8 files changed

+130
-11
lines changed

8 files changed

+130
-11
lines changed

Tomlet.Tests/CommentSerializationTests.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
using System;
2+
using System.Collections.Generic;
23
using Tomlet.Models;
34
using Tomlet.Tests.CommentProvider;
45
using Tomlet.Tests.TestModelClasses;
56
using Xunit;
7+
using Xunit.Abstractions;
68

79
namespace Tomlet.Tests;
810

911
public class CommentSerializationTests
1012
{
13+
public CommentSerializationTests(ITestOutputHelper testOutputHelper)
14+
{
15+
}
16+
1117
[Fact]
1218
public void CommentsOnSimpleKeyValuePairsWork()
1319
{
@@ -146,4 +152,59 @@ public void CommentProviderTest()
146152
doc.GetValue("InlineComment").Comments.InlineComment);
147153
Assert.Equal("PlainPrecedingComment", doc.GetValue("InlineComment").Comments.PrecedingComment);
148154
}
155+
156+
[Fact]
157+
public void PaddingLinesTest()
158+
{
159+
var data = new PaddingTestModel()
160+
{
161+
A = "str a",
162+
B = 1,
163+
C = new PaddingTestModel.NestedModel()
164+
{
165+
E = "str",
166+
F = 2,
167+
},
168+
D = new List<PaddingTestModel.NestedModel>()
169+
{
170+
new()
171+
{
172+
E = "str0",
173+
F = 0,
174+
},
175+
new()
176+
{
177+
E = "str1",
178+
F = 1,
179+
},
180+
}
181+
};
182+
183+
var expected = @"
184+
A = ""str a""
185+
B = 1
186+
187+
# Nested Object
188+
[C]
189+
# Preceding Comment
190+
E = ""str"" # Preceding Comment
191+
# Preceding Comment
192+
F = 2 # Preceding Comment
193+
194+
195+
# Nested Array
196+
[[D]]
197+
# Preceding Comment
198+
E = ""str0"" # Preceding Comment
199+
# Preceding Comment
200+
F = 0 # Preceding Comment
201+
202+
[[D]]
203+
# Preceding Comment
204+
E = ""str1"" # Preceding Comment
205+
# Preceding Comment
206+
F = 1 # Preceding Comment
207+
".Trim();
208+
Assert.Equal(expected.ReplaceLineEndings(), TomletMain.TomlStringFrom(data).ReplaceLineEndings().Trim());
209+
}
149210
}

Tomlet.Tests/TestModelClasses/CommentProviderTestModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public class CommentProviderTestModel
88
[TomlPrecedingCommentProvider(typeof(TestPrecedingCommentProvider), new object[] { "PrecedingComment" })]
99
[TomlInlineComment("PlainInlineComment")]
1010
public string PrecedingComment { get; set; }
11-
11+
1212
[TomlInlineCommentProvider(typeof(TestInlineCommentProvider), new object[] { "InlineComment" })]
1313
[TomlPrecedingComment("PlainPrecedingComment")]
1414
public string InlineComment { get; set; }
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System.Collections.Generic;
2+
using Tomlet.Attributes;
3+
4+
namespace Tomlet.Tests.TestModelClasses;
5+
6+
public class PaddingTestModel
7+
{
8+
public string A { get; set; }
9+
10+
public int B { get; set; }
11+
12+
[TomlPaddingLines(1)]
13+
[TomlDoNotInlineObject]
14+
[TomlPrecedingComment("Nested Object")]
15+
public NestedModel C { get; set; }
16+
17+
[TomlPaddingLines(1)]
18+
[TomlDoNotInlineObject]
19+
[TomlPrecedingComment("Nested Array")]
20+
public List<NestedModel> D { get; set; }
21+
22+
public class NestedModel
23+
{
24+
[TomlPrecedingComment("Preceding Comment")]
25+
[TomlInlineComment("Preceding Comment")]
26+
public string E { get; set; }
27+
28+
[TomlPrecedingComment("Preceding Comment")]
29+
[TomlInlineComment("Preceding Comment")]
30+
public int F { get; set; }
31+
}
32+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
3+
namespace Tomlet.Attributes;
4+
5+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Field | AttributeTargets.Property)]
6+
public class TomlPaddingLinesAttribute: Attribute
7+
{
8+
public int PaddingLines { get; }
9+
10+
public TomlPaddingLinesAttribute(int paddingLines)
11+
{
12+
PaddingLines = paddingLines;
13+
}
14+
}

Tomlet/Models/TomlArray.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,10 @@ public string SerializeTableArray(string key)
105105
//if we have a preceding comment on the array itself, we add a blank line
106106
//prior to the preceding comment on the first table.
107107
builder.Append('\n');
108-
108+
109+
if (first && value.Comments.PrecedingPaddingLines > 0)
110+
builder.Append('\n', value.Comments.PrecedingPaddingLines);
111+
109112
builder.Append(value.Comments.FormatPrecedingComment())
110113
.Append('\n');
111114
}

Tomlet/Models/TomlCommentData.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ namespace Tomlet.Models;
66

77
public class TomlCommentData
88
{
9+
public int PrecedingPaddingLines { get; set; } = 0;
10+
911
private string? _inlineComment;
1012

1113
public string? PrecedingComment { get; set; }
@@ -20,35 +22,35 @@ public string? InlineComment
2022
_inlineComment = null;
2123
return;
2224
}
23-
25+
2426
if (value.Contains("\n") || value.Contains("\r"))
2527
throw new TomlNewlineInInlineCommentException();
26-
28+
2729
_inlineComment = value;
2830
}
2931
}
30-
32+
3133
public bool ThereAreNoComments => InlineComment == null && PrecedingComment == null;
3234

3335
internal string FormatPrecedingComment(int indentCount = 0)
3436
{
35-
if(PrecedingComment == null)
37+
if (PrecedingComment == null)
3638
throw new Exception("Preceding comment is null");
3739

3840
var builder = new StringBuilder();
39-
41+
4042
var lines = PrecedingComment.Split('\n');
4143
var first = true;
4244
foreach (var line in lines)
4345
{
4446
if (!first)
4547
builder.Append('\n');
4648
first = false;
47-
49+
4850
var correctIndent = new string('\t', indentCount);
4951
builder.Append(correctIndent).Append("# ").Append(line);
5052
}
51-
53+
5254
return builder.ToString();
5355
}
5456
}

Tomlet/Models/TomlTable.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ private void WriteValueToStringBuilder(string? keyName, string subKey, StringBui
100100

101101
var hadBlankLine = builder.Length < 2 || builder[builder.Length - 2] == '\n';
102102

103+
if (value.Comments.PrecedingPaddingLines > 0)
104+
builder.Append('\n', value.Comments.PrecedingPaddingLines);
105+
103106
//Handle any preceding comment - this will ALWAYS go before any sort of value
104107
if (value.Comments.PrecedingComment != null)
105108
builder.Append(value.Comments.FormatPrecedingComment())

Tomlet/TomlCompositeSerializer.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ public static TomlSerializationMethods.Serialize<object> For(Type type, TomlSeri
3939
{
4040
inline = GenericExtensions.GetCustomAttribute<TomlInlineCommentProviderAttribute>(f),
4141
preceding = GenericExtensions.GetCustomAttribute<TomlPrecedingCommentProviderAttribute>(f),
42-
noInline = GenericExtensions.GetCustomAttribute<TomlDoNotInlineObjectAttribute>(f)
42+
noInline = GenericExtensions.GetCustomAttribute<TomlDoNotInlineObjectAttribute>(f),
43+
paddingLines = GenericExtensions.GetCustomAttribute<TomlPaddingLinesAttribute>(f),
4344
});
4445
var props = type.GetProperties(memberFlags)
4546
.ToArray();
@@ -49,7 +50,8 @@ public static TomlSerializationMethods.Serialize<object> For(Type type, TomlSeri
4950
inline = GenericExtensions.GetCustomAttribute<TomlInlineCommentProviderAttribute>(p),
5051
preceding = GenericExtensions.GetCustomAttribute<TomlPrecedingCommentProviderAttribute>(p),
5152
prop = GenericExtensions.GetCustomAttribute<TomlPropertyAttribute>(p),
52-
noInline = GenericExtensions.GetCustomAttribute<TomlDoNotInlineObjectAttribute>(p)
53+
noInline = GenericExtensions.GetCustomAttribute<TomlDoNotInlineObjectAttribute>(p),
54+
paddingLines = GenericExtensions.GetCustomAttribute<TomlPaddingLinesAttribute>(p),
5355
});
5456

5557
var isForcedNoInline = GenericExtensions.GetCustomAttribute<TomlDoNotInlineObjectAttribute>(type) != null;
@@ -94,6 +96,7 @@ public static TomlSerializationMethods.Serialize<object> For(Type type, TomlSeri
9496

9597
tomlValue.Comments.InlineComment = commentAttribs.inline?.GetComment();
9698
tomlValue.Comments.PrecedingComment = commentAttribs.preceding?.GetComment();
99+
tomlValue.Comments.PrecedingPaddingLines = commentAttribs.paddingLines?.PaddingLines ?? 0;
97100

98101
if(commentAttribs.noInline != null && tomlValue is TomlTable table)
99102
table.ForceNoInline = true;
@@ -123,6 +126,7 @@ public static TomlSerializationMethods.Serialize<object> For(Type type, TomlSeri
123126

124127
tomlValue.Comments.InlineComment = thisPropAttribs.inline?.GetComment();
125128
tomlValue.Comments.PrecedingComment = thisPropAttribs.preceding?.GetComment();
129+
tomlValue.Comments.PrecedingPaddingLines = thisPropAttribs.paddingLines?.PaddingLines ?? 0;
126130

127131
if (thisPropAttribs.noInline != null && tomlValue is TomlTable table)
128132
table.ForceNoInline = true;

0 commit comments

Comments
 (0)