Skip to content

Commit 0b54ad1

Browse files
committed
Add compress support to PSAppDeployToolkit.CodeGen.PowerShellSyntaxSerializer.
1 parent b82af7a commit 0b54ad1

2 files changed

Lines changed: 95 additions & 9 deletions

File tree

src/PSADT/PSAppDeployToolkit/CodeGen/PowerShellSyntaxSerializer.cs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,41 @@ namespace PSAppDeployToolkit.CodeGen
3434
/// It is typically used to generate PowerShell code or scripts that recreate the serialized objects.</remarks>
3535
public static class PowerShellSyntaxSerializer
3636
{
37+
/// <summary>
38+
/// Serializes the specified object to a PowerShell-compatible string representation.
39+
/// </summary>
40+
/// <remarks>The returned string can be used in PowerShell scripts to recreate the original object
41+
/// structure, where supported.</remarks>
42+
/// <param name="value">The object to serialize. Can be null.</param>
43+
/// <returns>A string containing the PowerShell syntax representation of the specified object. Returns an empty string if
44+
/// the value is null.</returns>
45+
public static string Serialize<T>(T value)
46+
{
47+
PowerShellSyntaxWriter writer = new();
48+
WriteValue(value, writer);
49+
return writer.ToString();
50+
}
51+
52+
/// <summary>
53+
/// Serializes the specified object to a PowerShell syntax string, with optional compression.
54+
/// </summary>
55+
/// <param name="value">The object to serialize. Can be null.</param>
56+
/// <param name="compress">true to compress the output; otherwise, false.</param>
57+
/// <returns>A string containing the PowerShell syntax representation of the serialized object.</returns>
58+
public static string Serialize<T>(T value, bool compress)
59+
{
60+
PowerShellSyntaxWriter writer = new(compress);
61+
WriteValue(value, writer);
62+
return writer.ToString();
63+
}
64+
3765
/// <summary>
3866
/// Serializes the specified value to a PowerShell-formatted string.
3967
/// </summary>
4068
/// <param name="value">The object to serialize. Can be null.</param>
4169
/// <param name="indentChars">The string to use for indentation in the output. Defaults to four spaces.</param>
4270
/// <returns>A string containing the PowerShell-formatted representation of the value.</returns>
43-
public static string Serialize<T>(T value, string indentChars = " ")
71+
public static string Serialize<T>(T value, string indentChars)
4472
{
4573
PowerShellSyntaxWriter writer = new(indentChars);
4674
WriteValue(value, writer);

src/PSADT/PSAppDeployToolkit/CodeGen/PowerShellSyntaxWriter.cs

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020

2121
using System;
22+
using System.Collections.Generic;
2223
using System.Management.Automation.Language;
2324
using System.Text;
2425

@@ -31,9 +32,28 @@ namespace PSAppDeployToolkit.CodeGen
3132
/// <remarks>This class is designed to assist in emitting valid, human-readable PowerShell code fragments,
3233
/// such as for code generation or serialization scenarios. It manages indentation and escaping automatically to
3334
/// produce syntactically correct output.</remarks>
34-
/// <param name="indentChars">The string used for each indentation level. Defaults to four spaces. Cannot be null.</param>
35-
internal sealed class PowerShellSyntaxWriter(string indentChars = " ")
35+
internal sealed class PowerShellSyntaxWriter()
3636
{
37+
/// <summary>
38+
/// Initializes a new instance of the PowerShellSyntaxWriter class with the specified compression option.
39+
/// </summary>
40+
/// <param name="compress">true to enable output compression; otherwise, false.</param>
41+
internal PowerShellSyntaxWriter(bool compress) : this()
42+
{
43+
_compress = compress;
44+
}
45+
46+
/// <summary>
47+
/// Initializes a new instance of the PowerShellSyntaxWriter class with the specified indentation characters.
48+
/// </summary>
49+
/// <param name="indentChars">The string of characters to use for indentation in the generated PowerShell syntax. Cannot be null or
50+
/// whitespace.</param>
51+
internal PowerShellSyntaxWriter(string indentChars) : this()
52+
{
53+
ArgumentException.ThrowIfNullOrWhiteSpace(indentChars);
54+
_indentChars = indentChars;
55+
}
56+
3757
/// <summary>
3858
/// Writes the opening token of a PowerShell hashtable literal (<c>@{</c>)
3959
/// or ordered dictionary literal (<c>[ordered]@{</c>) and increases the
@@ -46,6 +66,11 @@ internal void WriteStartHashtable(bool ordered = false)
4666
{
4767
_ = _buffer.Append(ordered ? "[ordered]@{" : "@{");
4868
_depth++;
69+
if (_compress)
70+
{
71+
_propertyWrittenStack.Push(_propertyWritten);
72+
_propertyWritten = false;
73+
}
4974
}
5075

5176
/// <summary>
@@ -55,9 +80,17 @@ internal void WriteStartHashtable(bool ordered = false)
5580
internal void WriteEndHashtable()
5681
{
5782
_depth--;
58-
_ = _buffer.AppendLine();
59-
WriteIndent();
60-
_ = _buffer.Append('}');
83+
if (_compress)
84+
{
85+
_ = _buffer.Append(" }");
86+
_propertyWritten = _propertyWrittenStack.Pop();
87+
}
88+
else
89+
{
90+
_ = _buffer.AppendLine();
91+
WriteIndent();
92+
_ = _buffer.Append('}');
93+
}
6194
}
6295

6396
/// <summary>
@@ -68,8 +101,16 @@ internal void WriteEndHashtable()
68101
internal void WritePropertyName(string name)
69102
{
70103
ArgumentNullException.ThrowIfNull(name);
71-
_ = _buffer.AppendLine();
72-
WriteIndent();
104+
if (_compress)
105+
{
106+
_ = _buffer.Append(_propertyWritten ? "; " : " ");
107+
_propertyWritten = true;
108+
}
109+
else
110+
{
111+
_ = _buffer.AppendLine();
112+
WriteIndent();
113+
}
73114
_ = _buffer.Append(name);
74115
_ = _buffer.Append(" = ");
75116
}
@@ -146,6 +187,8 @@ internal void Reset()
146187
{
147188
_ = _buffer.Clear();
148189
_depth = 0;
190+
_propertyWritten = false;
191+
_propertyWrittenStack.Clear();
149192
}
150193

151194
/// <summary>
@@ -176,19 +219,34 @@ private void WriteIndent()
176219
/// </summary>
177220
private int _depth;
178221

222+
/// <summary>
223+
/// Tracks whether a property has been written at the current hashtable depth (compressed mode).
224+
/// </summary>
225+
private bool _propertyWritten;
226+
227+
/// <summary>
228+
/// When <see langword="true"/>, hashtables are emitted on a single line with semicolons.
229+
/// </summary>
230+
private readonly bool _compress;
231+
179232
/// <summary>
180233
/// Stores the string used for indentation in formatted output.
181234
/// </summary>
182235
/// <remarks>This field is initialized with the value provided to the constructor and cannot be
183236
/// null. It is typically used to control the appearance of indented text, such as in pretty-printing or
184237
/// structured formatting scenarios.</remarks>
185-
private readonly string _indentChars = indentChars ?? throw new ArgumentNullException(nameof(indentChars));
238+
private readonly string _indentChars = " ";
186239

187240
/// <summary>
188241
/// Represents the internal buffer used to accumulate or manipulate string data for this instance.
189242
/// </summary>
190243
/// <remarks>This field is intended for internal use and is not exposed to consumers of the class.
191244
/// Its contents may change as operations are performed.</remarks>
192245
private readonly StringBuilder _buffer = new();
246+
247+
/// <summary>
248+
/// Saves <see cref="_propertyWritten"/> state when entering nested hashtables.
249+
/// </summary>
250+
private readonly Stack<bool> _propertyWrittenStack = new();
193251
}
194252
}

0 commit comments

Comments
 (0)