/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
namespace Microsoft.Rest.ClientRuntime
{
using System;
///
/// PowerShell-specific data on top of the llc# EventData
///
///
/// In PowerShell, we add on the EventDataConverter to support sending events between modules.
/// Obviously, this code would need to be duplcated on both modules.
/// This is preferable to sharing a common library, as versioning makes that problematic.
///
[System.ComponentModel.TypeConverter(typeof(EventDataConverter))]
public partial class EventData : EventArgs
{
}
///
/// A PowerShell PSTypeConverter to adapt an EventData object that has been passed.
/// Usually used between modules.
///
public class EventDataConverter : System.Management.Automation.PSTypeConverter
{
public override bool CanConvertTo(object sourceValue, Type destinationType) => false;
public override object ConvertTo(object sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase) => null;
public override bool CanConvertFrom(dynamic sourceValue, Type destinationType) => destinationType == typeof(EventData) && CanConvertFrom(sourceValue);
public override object ConvertFrom(dynamic sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase) => ConvertFrom(sourceValue);
///
/// Verifies that a given object has the required members to convert it to the target type (EventData)
///
/// Uses a dynamic type so that it is able to use the simplest code without excessive checking.
///
/// The instance to verify
/// True, if the object has all the required parameters.
public static bool CanConvertFrom(dynamic sourceValue)
{
try
{
// check if this has *required* parameters...
sourceValue?.Id?.GetType();
sourceValue?.Message?.GetType();
sourceValue?.Cancel?.GetType();
// remaining parameters are not *required*,
// and if they have values, it will copy them at conversion time.
}
catch
{
// if anything throws an exception (because it's null, or doesn't have that member)
return false;
}
return true;
}
///
/// Returns result of the delegate as the expected type, or default(T)
///
/// This isolates any exceptions from the consumer.
///
/// A delegate that returns a value
/// The desired output type
/// The value from the function if the type is correct
private static T To(Func srcValue)
{
try { return srcValue(); }
catch { return default(T); }
}
///
/// Converts an incoming object to the expected type by treating the incoming object as a dynamic, and coping the expected values.
///
/// the incoming object
/// EventData
public static EventData ConvertFrom(dynamic sourceValue)
{
return new EventData
{
Id = To(() => sourceValue.Id),
Message = To(() => sourceValue.Message),
Parameter = To(() => sourceValue.Parameter),
Value = To(() => sourceValue.Value),
RequestMessage = To(() => sourceValue.RequestMessage),
ResponseMessage = To(() => sourceValue.ResponseMessage),
Cancel = To(() => sourceValue.Cancel)
};
}
}
}