-
Notifications
You must be signed in to change notification settings - Fork 111
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
added method to detect if a yaml fragment is a sequence #720
Changes from all commits
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 |
---|---|---|
|
@@ -128,5 +128,45 @@ private static void WriteTextWriter<TValue>(TextWriter writer, in TValue? value, | |
// See: fluentvalidation.net | ||
// See: https://www.youtube.com/watch?v=jblRYDMTtvg | ||
} | ||
|
||
/// <summary> | ||
/// checks the input source is a sequence of YAML items. | ||
/// </summary> | ||
/// <param name="yaml">The YAML text to check.</param> | ||
/// <returns></returns> | ||
/// <exception cref="ArgumentNullException"></exception> | ||
public static bool CheckIsSequence(string yaml) | ||
{ | ||
_ = yaml ?? throw new ArgumentNullException(nameof(yaml)); | ||
|
||
using var reader = new StringReader(yaml); | ||
return CheckIsSequence(reader); | ||
} | ||
|
||
/// <summary> | ||
/// checks the input source is a sequence of YAML items. | ||
/// </summary> | ||
/// <param name="reader"></param> | ||
/// <returns></returns> | ||
/// <exception cref="ArgumentNullException"></exception> | ||
public static bool CheckIsSequence(StringReader reader) | ||
{ | ||
ArgumentNullException.ThrowIfNull(reader); | ||
|
||
var builder = new DeserializerBuilder() | ||
.IgnoreUnmatchedProperties() | ||
.WithTypeConverter(new YamlSequenceTesterConverter()); | ||
var deserializer = builder.Build(); | ||
try | ||
{ | ||
var results = deserializer.Deserialize<object[]>(reader); | ||
return results is not null; | ||
} | ||
catch (YamlException) | ||
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. we should not need to use exceptions as control-flow. Another design option would be to deseralize into a custom type, register a converter for that type, and in the converter populate a property which has the 'result' of the detection. e..g private record SequenceDetectorResult
{
public required bool IsSequence { get; init; }
} |
||
{ | ||
return false; | ||
} | ||
} | ||
|
||
#endregion | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using System.Collections; | ||
using YamlDotNet.Core; | ||
using YamlDotNet.Core.Events; | ||
using YamlDotNet.Serialization; | ||
|
||
namespace Microsoft.PowerPlatform.PowerApps.Persistence.PaYaml.Serialization; | ||
|
||
/// <summary> | ||
/// custom converter used to test if the input is a sequence of YAML items. | ||
/// </summary> | ||
internal sealed class YamlSequenceTesterConverter : IYamlTypeConverter | ||
{ | ||
public bool Accepts(Type type) | ||
{ | ||
return type == typeof(IEnumerable) || type.IsSubclassOf(typeof(IEnumerable)) || | ||
type == typeof(IEnumerable<object>) || type.IsSubclassOf(typeof(IEnumerable<object>)) || | ||
type == typeof(object[]); | ||
} | ||
|
||
public object? ReadYaml(IParser parser, Type type) | ||
{ | ||
if (parser.Current is not SequenceStart) | ||
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. when using the the benefit here is that there wouldn't be an exception thrown for code flow control. |
||
throw new YamlException(parser.Current!.Start, parser.Current.End, $"Expected sequence start but got {parser.Current.GetType().Name}"); | ||
|
||
while (!parser.Accept<SequenceEnd>(out _)) | ||
{ | ||
parser.MoveNext(); | ||
} | ||
|
||
parser.MoveNext(); | ||
|
||
return Array.Empty<object>(); | ||
} | ||
|
||
public void WriteYaml(IEmitter emitter, object? value, Type type) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please simplify this unit tests so it doesn't require external files for the baseline cases.
use targeted input strings for testing, don't use existing large files as these can change due to their purpose etc.