Skip to content

Commit

Permalink
PR fb and implement Set
Browse files Browse the repository at this point in the history
  • Loading branch information
annelo-msft committed Feb 17, 2023
1 parent 29dc9a7 commit f3fbd5c
Show file tree
Hide file tree
Showing 7 changed files with 322 additions and 144 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,30 +152,18 @@ public void Reset() { }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
}
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct DynamicJsonOptions
public enum DynamicJsonNameMapping
{
private int _dummyPrimitive;
public DynamicJsonOptions() { throw null; }
public Azure.Core.Dynamic.DynamicJsonPropertyCasing PropertyCasing { get { throw null; } set { } }
None = 0,
PascalCaseGetters = 1,
PascalCaseGettersCamelCaseSetters = 2,
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct DynamicJsonPropertyCasing
public partial struct DynamicJsonOptions
{
private int _dummyPrimitive;
public static readonly Azure.Core.Dynamic.DynamicJsonPropertyCasing Default;
public Azure.Core.Dynamic.ExistingPropertyCasing ExistingPropertyAccess { get { throw null; } set { } }
public Azure.Core.Dynamic.NewPropertyCasing NewPropertyAccess { get { throw null; } set { } }
}
public enum ExistingPropertyCasing
{
CaseSensitive = 0,
AllowPascalCase = 1,
}
public enum NewPropertyCasing
{
CaseSensitive = 0,
WriteCamelCase = 1,
public DynamicJsonOptions() { throw null; }
public Azure.Core.Dynamic.DynamicJsonNameMapping PropertyNameCasing { get { throw null; } set { } }
}
}
namespace Azure.Core.Json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,30 +152,18 @@ public void Reset() { }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
}
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct DynamicJsonOptions
public enum DynamicJsonNameMapping
{
private int _dummyPrimitive;
public DynamicJsonOptions() { throw null; }
public Azure.Core.Dynamic.DynamicJsonPropertyCasing PropertyCasing { get { throw null; } set { } }
None = 0,
PascalCaseGetters = 1,
PascalCaseGettersCamelCaseSetters = 2,
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct DynamicJsonPropertyCasing
public partial struct DynamicJsonOptions
{
private int _dummyPrimitive;
public static readonly Azure.Core.Dynamic.DynamicJsonPropertyCasing Default;
public Azure.Core.Dynamic.ExistingPropertyCasing ExistingPropertyAccess { get { throw null; } set { } }
public Azure.Core.Dynamic.NewPropertyCasing NewPropertyAccess { get { throw null; } set { } }
}
public enum ExistingPropertyCasing
{
CaseSensitive = 0,
AllowPascalCase = 1,
}
public enum NewPropertyCasing
{
CaseSensitive = 0,
WriteCamelCase = 1,
public DynamicJsonOptions() { throw null; }
public Azure.Core.Dynamic.DynamicJsonNameMapping PropertyNameCasing { get { throw null; } set { } }
}
}
namespace Azure.Core.Json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,30 +152,18 @@ public void Reset() { }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
}
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct DynamicJsonOptions
public enum DynamicJsonNameMapping
{
private int _dummyPrimitive;
public DynamicJsonOptions() { throw null; }
public Azure.Core.Dynamic.DynamicJsonPropertyCasing PropertyCasing { get { throw null; } set { } }
None = 0,
PascalCaseGetters = 1,
PascalCaseGettersCamelCaseSetters = 2,
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct DynamicJsonPropertyCasing
public partial struct DynamicJsonOptions
{
private int _dummyPrimitive;
public static readonly Azure.Core.Dynamic.DynamicJsonPropertyCasing Default;
public Azure.Core.Dynamic.ExistingPropertyCasing ExistingPropertyAccess { get { throw null; } set { } }
public Azure.Core.Dynamic.NewPropertyCasing NewPropertyAccess { get { throw null; } set { } }
}
public enum ExistingPropertyCasing
{
CaseSensitive = 0,
AllowPascalCase = 1,
}
public enum NewPropertyCasing
{
CaseSensitive = 0,
WriteCamelCase = 1,
public DynamicJsonOptions() { throw null; }
public Azure.Core.Dynamic.DynamicJsonNameMapping PropertyNameCasing { get { throw null; } set { } }
}
}
namespace Azure.Core.Json
Expand Down
47 changes: 45 additions & 2 deletions sdk/core/Azure.Core.Experimental/src/DynamicJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Xml.Linq;
using Azure.Core.Json;

namespace Azure.Core.Dynamic
Expand Down Expand Up @@ -48,8 +49,7 @@ internal override void WriteTo(Stream stream)
return new DynamicJson(element);
}

if (_options.PropertyCasing.ExistingPropertyAccess == ExistingPropertyCasing.AllowPascalCase &&
char.IsUpper(name[0]))
if (PascalCaseGetters() && char.IsUpper(name[0]))
{
if (_element.TryGetProperty(GetAsCamelCase(name), out element))
{
Expand All @@ -60,6 +60,18 @@ internal override void WriteTo(Stream stream)
return null;
}

private bool PascalCaseGetters()
{
return
_options.PropertyNameCasing == DynamicJsonNameMapping.PascalCaseGetters ||
_options.PropertyNameCasing == DynamicJsonNameMapping.PascalCaseGettersCamelCaseSetters;
}

private bool CamelCaseSetters()
{
return _options.PropertyNameCasing == DynamicJsonNameMapping.PascalCaseGettersCamelCaseSetters;
}

private static string GetAsCamelCase(string value)
{
return $"{char.ToLowerInvariant(value[0])}{value.Substring(1)}";
Expand All @@ -85,6 +97,37 @@ private IEnumerable GetEnumerable()

private object? SetProperty(string name, object value)
{
Argument.AssertNotNullOrEmpty(name, nameof(name));

if (_options.PropertyNameCasing == DynamicJsonNameMapping.None)
{
_element = _element.SetProperty(name, value);
return null;
}

if (!char.IsUpper(name[0]))
{
// Lookup name is camelCase, so set unchanged.
_element = _element.SetProperty(name, value);
return null;
}

// Other mappings have PascalCase getters, and lookup name is PascalCase.
// So, if it exists in either form, we'll set it in that form.
if (_element.TryGetProperty(name, out MutableJsonElement element))
{
element.Set(value);
return null;
}

if (_element.TryGetProperty(GetAsCamelCase(name), out element))
{
element.Set(value);
return null;
}

// It's a new property, so set according to the mapping.
name = CamelCaseSetters() ? GetAsCamelCase(name) : name;
_element = _element.SetProperty(name, value);

// Binding machinery expects the call site signature to return an object
Expand Down
31 changes: 31 additions & 0 deletions sdk/core/Azure.Core.Experimental/src/DynamicJsonNameMapping.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;

namespace Azure.Core.Dynamic
{
/// <summary>
/// Options for setting new DynamicJson properties.
/// </summary>
public enum DynamicJsonNameMapping
{
/// <summary>
/// Properties are accessed and written in the JSON buffer with the same casing as the DynamicJson property.
/// </summary>
None = 0,

/// <summary>
/// A "PascalCase" DynamicJson property can be used to read and set "camelCase" properties that exist in the JSON buffer.
/// New properties are written to the JSON buffer with the same casing as the DynamicJson property.
/// </summary>
PascalCaseGetters = 1,

/// <summary>
/// Default settings for Azure services.
/// A "PascalCase" DynamicJson property can be used to read and set "camelCase" properties that exist in the JSON buffer.
/// New properties are written to the JSON buffer using "camelCase" property names.
/// </summary>
PascalCaseGettersCamelCaseSetters = 2
}
}
62 changes: 2 additions & 60 deletions sdk/core/Azure.Core.Experimental/src/DynamicJsonOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,66 +16,8 @@ public struct DynamicJsonOptions
public DynamicJsonOptions() { }

/// <summary>
/// Specifies how properties on <see cref="DynamicJson"/> will get accessed in the underlying JSON buffer.
/// Specifies how properties on <see cref="DynamicJson"/> will be accessed in the underlying JSON buffer.
/// </summary>
public DynamicJsonPropertyCasing PropertyCasing { get; set; } = DynamicJsonPropertyCasing.Default;
}

/// <summary>
/// Casing options for property access on DynamicJson.
/// </summary>
public struct DynamicJsonPropertyCasing
{
/// <summary>
/// Default settings for property access casing in DynamicJson.
/// </summary>
public static readonly DynamicJsonPropertyCasing Default = new()
{
ExistingPropertyAccess = ExistingPropertyCasing.AllowPascalCase,
NewPropertyAccess = NewPropertyCasing.WriteCamelCase
};

/// <summary>
/// How DynamicJson property accessors will map to properties in the JSON buffer.
/// </summary>
public ExistingPropertyCasing ExistingPropertyAccess { get; set; }

/// <summary>
/// How DynamicJson property accessors will create new properties in the JSON buffer.
/// </summary>
public NewPropertyCasing NewPropertyAccess { get; set; }
}

/// <summary>
/// Options for setting new DyanmicJson properties.
/// </summary>
public enum NewPropertyCasing
{
/// <summary>
/// New properties are written with the same casing as the DynamicJson property.
/// </summary>
CaseSensitive = 0,

/// <summary>
/// A "PascalCase" DynamicJson property will be written as a "camelCase" property in the JSON buffer.
/// "camelCase" DynamicJson properties will be written in the JSON buffer unchanged.
/// </summary>
WriteCamelCase = 1
}

/// <summary>
/// Options for accessing existing DyanmicJson properties.
/// </summary>
public enum ExistingPropertyCasing
{
/// <summary>
/// The DynamicJson property matches the casing in the JSON buffer exactly.
/// </summary>
CaseSensitive = 0,

/// <summary>
/// A "PascalCase" DynamicJson property can read a "camelCase" property from the JSON buffer.
/// </summary>
AllowPascalCase = 1
public DynamicJsonNameMapping PropertyNameCasing { get; set; } = DynamicJsonNameMapping.PascalCaseGettersCamelCaseSetters;
}
}
Loading

0 comments on commit f3fbd5c

Please sign in to comment.