Skip to content

Commit

Permalink
Support Char format for string (Azure#1252)
Browse files Browse the repository at this point in the history
  • Loading branch information
fearthecowboy authored Jul 12, 2016
1 parent 0da7d34 commit 5069891
Show file tree
Hide file tree
Showing 14 changed files with 883 additions and 132 deletions.
3 changes: 2 additions & 1 deletion AutoRest.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderText/@EntryValue">Copyright (c) Microsoft Corporation. All rights reserved.&#xD;
Licensed under the MIT License. See License.txt in the project root for license information.&#xD;
&#xD;
</s:String></wpf:ResourceDictionary>
</s:String>
<s:Boolean x:Key="/Default/Environment/UnitTesting/ShadowCopy/@EntryValue">False</s:Boolean></wpf:ResourceDictionary>
32 changes: 32 additions & 0 deletions src/core/AutoRest.Core/ClientModel/KnownFormat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
//

using System.Diagnostics.CodeAnalysis;

namespace AutoRest.Core.ClientModel
{
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum KnownFormat
{
none,
unknown,

@char,
int32,
int64,
@float,
@double,
@byte,
binary,
date,
date_time,
password,
date_time_rfc1123,
duration,
uuid,
base64url,
@decimal,
unixtime
}
}
22 changes: 22 additions & 0 deletions src/core/AutoRest.Core/ClientModel/KnownFormatExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
//

using System;

namespace AutoRest.Core.ClientModel
{
public static class KnownFormatExtensions
{
public static KnownFormat Parse(string formatValue)
{
if (string.IsNullOrWhiteSpace(formatValue))
{
return KnownFormat.none;
}

KnownFormat result;
return Enum.TryParse(formatValue.Replace('-', '_'), true, out result) ? result : KnownFormat.unknown;
}
}
}
6 changes: 6 additions & 0 deletions src/core/AutoRest.Core/ClientModel/PrimaryType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ public PrimaryType(KnownPrimaryType type)
/// </summary>
public string Format { get; set; }

/// <summary>
/// Returns the KnownFormat of the Format string (provided it matches a KnownFormat)
/// Otherwise, returns KnownFormat.none
/// </summary>
public KnownFormat KnownFormat => KnownFormatExtensions.Parse(Format);

/// <summary>
/// Returns a string representation of the PrimaryType object.
/// </summary>
Expand Down
2 changes: 2 additions & 0 deletions src/core/AutoRest.Core/Logging/Logger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ static Logger()
/// <param name="args">Optional arguments to use if message includes formatting.</param>
public static void LogInfo(string message, params object[] args)
{
lock( typeof( Logger ) ) {
Entries.Add(new LogEntry(LogEntrySeverity.Info, string.Format(CultureInfo.InvariantCulture, message, args)));
}
}

/// <summary>
Expand Down
258 changes: 258 additions & 0 deletions src/generator/AutoRest.CSharp.Unit.Tests/AutoDynamic.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
//

using System;
using System.Collections;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;

namespace AutoRest.CSharp.Unit.Tests
{
/// <summary>
/// This is a class that creates a dynamic wrapper around any object and can allow
/// deep inspection of anything (private or otherwise).
/// Handy for testing.
/// </summary>
public class AutoDynamic : DynamicObject
{
/// <summary>
/// Specify the flags for accessing members
/// </summary>
private static readonly BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance
| BindingFlags.Static | BindingFlags.Public
| BindingFlags.IgnoreCase;

/// <summary>
/// The object we are going to wrap
/// </summary>
private readonly object _wrapped;

/// <summary>
/// Create a simple private wrapper
/// </summary>
public AutoDynamic(object o)
{
_wrapped = o;
}

/// <summary>
/// Returns a JSON representation.
/// </summary>
/// <returns>a JSON string</returns>
public string ToJson()
{
return JsonConvert.SerializeObject(
_wrapped,
Formatting.Indented,
new JsonSerializerSettings
{
Converters = new JsonConverter[] {new StringEnumConverter()},
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore,
ObjectCreationHandling = ObjectCreationHandling.Reuse
});
}

private bool CheckResult(object result, out object outresult)
{
if (result == null || result.GetType().GetTypeInfo().IsPrimitive
|| result.GetType().GetTypeInfo().IsValueType || result is string)
{
outresult = result;
}
else
{
outresult = result.ToDynamic();
}

return true;
}

/// <summary>
/// Try invoking a method
/// </summary>
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if (_wrapped == null)
{
result = null;
return true;
}
var types = args.Select(a => a != null ? a.GetType() : typeof(object));

var method = _wrapped.GetType().GetMethod(binder.Name, types.ToArray())
?? _wrapped.GetType().GetMethod(binder.Name, flags);

if (method == null)
{
return base.TryInvokeMember(binder, args, out result);
}

return CheckResult(method.Invoke(_wrapped, args), out result);
}

public override bool TryConvert(ConvertBinder binder, out object result)
{
if (_wrapped == null)
{
result = null;
return false;
}

if (binder.ReturnType.IsInstanceOfType(_wrapped))
{
result = _wrapped;
return true;
}
return base.TryConvert(binder, out result);
}

public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
if (_wrapped == null)
{
result = null;
return false;
}

if (indexes.Length == 1 && indexes[0] is int)
{
var index = (int) indexes[0];
try
{
var arr = _wrapped as Array;
if (arr != null)
{
return CheckResult(arr.GetValue(index), out result);
}
}
catch
{
// nope...
}
}

// is it asking for a property as a field
foreach (
var prop in _wrapped.GetType().GetProperties(flags).Where(each => each.GetIndexParameters().Any()))
{
try
{
result = prop.GetValue(_wrapped, indexes);
return true;
}
catch (TargetParameterCountException)
{
}
catch (TargetInvocationException)
{
}
}

if (indexes.Length == 1 && indexes[0] is int)
{
var index = (int) indexes[0];
try
{
var ie = _wrapped as IEnumerable;
if (ie != null)
{
var e = ie.GetEnumerator();

while (index > 0 && e.MoveNext())
{
--index;
}
if (index == 0)
{
if (e.MoveNext())
{
return CheckResult(e.Current, out result);
}
}
}
}
catch
{
}
}
return base.TryGetIndex(binder, indexes, out result);
}

/// <summary>
/// Tries to get a property or field with the given name
/// </summary>
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (_wrapped == null)
{
result = null;
return true;
}

try
{
//Try getting a property of that name
var prop = _wrapped.GetType().GetProperty(binder.Name, flags);

if (prop == null)
{
//Try getting a field of that name
var fld = _wrapped.GetType().GetField(binder.Name, flags);

if (fld != null)
{
return CheckResult(fld.GetValue(_wrapped), out result);
}

// check if this is an index into the
if (TryGetIndex(null, new[] {binder.Name}, out result))
{
return true;
}

return base.TryGetMember(binder, out result);
}
return CheckResult(prop.GetValue(_wrapped, null), out result);
}
catch (Exception e)
{
Debug.WriteLine($"{e.Message}/{e.StackTrace}");
result = null;
return true;
}
}

/// <summary>
/// Tries to set a property or field with the given name
/// </summary>
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (_wrapped == null)
{
return false;
}

var prop = _wrapped.GetType().GetProperty(binder.Name, flags);
if (prop == null)
{
var fld = _wrapped.GetType().GetField(binder.Name, flags);
if (fld != null)
{
fld.SetValue(_wrapped, value);
return true;
}
return base.TrySetMember(binder, value);
}

prop.SetValue(_wrapped, value, null);
return true;
}
}
}
Loading

0 comments on commit 5069891

Please sign in to comment.