Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,56 +5,44 @@
namespace Microsoft.Azure.Search.Serialization
{
using System;
using System.Linq;
using System.Reflection;
using Common;
using Models;
using Newtonsoft.Json;

/// <summary>
/// Delegate type for a factory method that creates or looks up an ExtensibleEnum instance from a given string.
/// </summary>
/// <typeparam name="T">The type of ExtensibleEnum returned.</typeparam>
/// <param name="name">The enum value to look up or create.</param>
/// <returns>An instance of type T.</returns>
public delegate T ExtensibleEnumValueFactory<T>(string name) where T : ExtensibleEnum<T>;

/// <summary>
/// Serializes and deserializes "extensible enums" to and from JSON. Extensible enums are like enumerations in
/// that they have well-known values, but they are extensible with new values and the values are based on strings
/// instead of integers.
/// </summary>
public class ExtensibleEnumConverter<T> : JsonConverter where T : ExtensibleEnum<T>
public class ExtensibleEnumConverter<T> : JsonConverter
{
private ExtensibleEnumValueFactory<T> _enumValueFactory;
private readonly Func<string, T> _enumValueFactory;

/// <summary>
/// Initializes a new instance of the ExtensibleEnumConverter class.
/// </summary>
public ExtensibleEnumConverter() : this("Create") { }

/// <summary>
/// Initializes a new instance of the ExtensibleEnumConverter class.
/// </summary>
/// <param name="factoryMethodName">
/// The name of a public static method that creates an instance of type T given a string value; Default is
/// "Create".
/// </param>
public ExtensibleEnumConverter(string factoryMethodName)
public ExtensibleEnumConverter()
{
Throw.IfArgumentNull(factoryMethodName, "factoryMethodName");
bool TakesSingleStringParameter(ConstructorInfo ctor)
{
ParameterInfo[] parameters = ctor.GetParameters();
if (parameters.Length == 1)
{
return parameters[0].ParameterType == typeof(string);
}

MethodInfo method = typeof(T).GetTypeInfo().GetDeclaredMethod(factoryMethodName);
return false;
}

const string MessageFormat =
"No method named '{0}' could be found that is convertible to ExtensibleEnumValueFactory<{1}>.";
ConstructorInfo fromStringCtor = typeof(T).GetTypeInfo().DeclaredConstructors.FirstOrDefault(TakesSingleStringParameter);

Throw.IfArgument(
method == null,
"factoryMethodName",
String.Format(MessageFormat, factoryMethodName, typeof(T).Name));
fromStringCtor == null,
typeof(T).Name,
$"No constructor taking a string parameter could be found for type '{typeof(T)}'.");

_enumValueFactory =
(ExtensibleEnumValueFactory<T>)method.CreateDelegate(typeof(ExtensibleEnumValueFactory<T>));
_enumValueFactory = str => (T)fromStringCtor.Invoke(new[] { str });
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@
// Licensed under the MIT License. See License.txt in the project root for
// license information.

using System;
using Microsoft.Azure.Search.Common;
using Microsoft.Azure.Search.Serialization;
using Newtonsoft.Json;
using System;

namespace Microsoft.Azure.Search.Models
{
/// <summary>
/// Defines the type of an Azure Search datasource.
/// </summary>
[JsonConverter(typeof(ExtensibleEnumConverter<DataSourceType>))]
public sealed class DataSourceType : ExtensibleEnum<DataSourceType>
public struct DataSourceType : IEquatable<DataSourceType>
{
private readonly string _value;

/// <summary>
/// Indicates an Azure SQL datasource.
/// </summary>
Expand All @@ -40,24 +43,66 @@ public sealed class DataSourceType : ExtensibleEnum<DataSourceType>
/// </summary>
public static readonly DataSourceType AzureTable = new DataSourceType("azuretable");

private DataSourceType(string typeName) : base(typeName)
private DataSourceType(string typeName)
{
// Base class does all initialization.
Throw.IfArgumentNull(typeName, nameof(typeName));
_value = typeName;
}

/// <summary>
/// Creates a new DataSourceType instance, or returns an existing instance if the given name matches that of a
/// known data source type.
/// Defines implicit conversion from string to DataSourceType.
/// </summary>
/// <param name="name">Name of the data source type.</param>
/// <returns>A DataSourceType instance with the given name.</returns>
public static DataSourceType Create(string name) => Lookup(name) ?? new DataSourceType(name);
/// <param name="value">string to convert.</param>
/// <returns>The string as a DataSourceType.</returns>
public static implicit operator DataSourceType(string value) => new DataSourceType(value);

/// <summary>
/// Defines implicit conversion from string to DataSourceType.
/// Defines explicit conversion from DataSourceType to string.
/// </summary>
/// <param name="name">string to convert.</param>
/// <returns>The string as a DataSourceType.</returns>
public static implicit operator DataSourceType(string name) => Create(name);
/// <param name="dataSourceType">DataSourceType to convert.</param>
/// <returns>The DataSourceType as a string.</returns>
public static explicit operator string(DataSourceType dataSourceType) => dataSourceType.ToString();

/// <summary>
/// Compares two DataSourceType values for equality.
/// </summary>
/// <param name="lhs">The first DataSourceType to compare.</param>
/// <param name="rhs">The second DataSourceType to compare.</param>
/// <returns>true if the DataSourceType objects are equal or are both null; false otherwise.</returns>
public static bool operator ==(DataSourceType lhs, DataSourceType rhs) => Equals(lhs, rhs);

/// <summary>
/// Compares two DataSourceType values for inequality.
/// </summary>
/// <param name="lhs">The first DataSourceType to compare.</param>
/// <param name="rhs">The second DataSourceType to compare.</param>
/// <returns>true if the DataSourceType objects are not equal; false otherwise.</returns>
public static bool operator !=(DataSourceType lhs, DataSourceType rhs) => !Equals(lhs, rhs);

/// <summary>
/// Compares the DataSourceType for equality with another DataSourceType.
/// </summary>
/// <param name="other">The DataSourceType with which to compare.</param>
/// <returns><c>true</c> if the DataSourceType objects are equal; otherwise, <c>false</c>.</returns>
public bool Equals(DataSourceType other) => _value == other._value;

/// <summary>
/// Determines whether the specified object is equal to the current object.
/// </summary>
/// <param name="obj">The object to compare with the current object.</param>
/// <returns><c>true</c> if the specified object is equal to the current object; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj) => obj is DataSourceType ? Equals((DataSourceType)obj) : false;

/// <summary>
/// Serves as the default hash function.
/// </summary>
/// <returns>A hash code for the current object.</returns>
public override int GetHashCode() => _value.GetHashCode();

/// <summary>
/// Returns a string representation of the DataSourceType.
/// </summary>
/// <returns>The DataSourceType as a string.</returns>
public override string ToString() => _value;
}
}
Loading