diff --git a/AutoRest/AutoRest.Core/ClientModel/KnownPrimaryType.cs b/AutoRest/AutoRest.Core/ClientModel/KnownPrimaryType.cs index 200dcfe018..94dd5ffd7b 100644 --- a/AutoRest/AutoRest.Core/ClientModel/KnownPrimaryType.cs +++ b/AutoRest/AutoRest.Core/ClientModel/KnownPrimaryType.cs @@ -25,6 +25,7 @@ public enum KnownPrimaryType Boolean, Credentials, Uuid, - Base64Url + Base64Url, + UnixTime } } diff --git a/AutoRest/Generators/CSharp/CSharp/CSharpCodeNamer.cs b/AutoRest/Generators/CSharp/CSharp/CSharpCodeNamer.cs index d9562cf4ca..3504b01cb5 100644 --- a/AutoRest/Generators/CSharp/CSharp/CSharpCodeNamer.cs +++ b/AutoRest/Generators/CSharp/CSharp/CSharpCodeNamer.cs @@ -297,6 +297,10 @@ protected virtual IType NormalizePrimaryType(PrimaryType primaryType) { primaryType.Name = "ServiceClientCredentials"; } + else if (primaryType.Type == KnownPrimaryType.UnixTime) + { + primaryType.Name = "DateTime"; + } else if (primaryType.Type == KnownPrimaryType.Uuid) { primaryType.Name = "Guid"; @@ -401,7 +405,8 @@ public override string EscapeDefaultValue(string defaultValue, IType type) primaryType.Type == KnownPrimaryType.DateTimeRfc1123 || primaryType.Type == KnownPrimaryType.TimeSpan || primaryType.Type == KnownPrimaryType.ByteArray || - primaryType.Type == KnownPrimaryType.Base64Url) + primaryType.Type == KnownPrimaryType.Base64Url || + primaryType.Type == KnownPrimaryType.UnixTime) { return "SafeJsonConvert.DeserializeObject<" + primaryType.Name.TrimEnd('?') + diff --git a/AutoRest/Generators/CSharp/CSharp/ClientModelExtensions.cs b/AutoRest/Generators/CSharp/CSharp/ClientModelExtensions.cs index ded2055e68..ae4d9f1115 100644 --- a/AutoRest/Generators/CSharp/CSharp/ClientModelExtensions.cs +++ b/AutoRest/Generators/CSharp/CSharp/ClientModelExtensions.cs @@ -225,6 +225,10 @@ public static string ToString(this IType type, string clientReference, string re { serializationSettings = "new Base64UrlJsonConverter()"; } + else if (primaryType.Type == KnownPrimaryType.UnixTime) + { + serializationSettings = "new UnixTimeJsonConverter()"; + } } return string.Format(CultureInfo.InvariantCulture, @@ -268,6 +272,7 @@ public static bool IsValueType(this IType type) || primaryType.Type == KnownPrimaryType.Long || primaryType.Type == KnownPrimaryType.TimeSpan || primaryType.Type == KnownPrimaryType.DateTimeRfc1123 + || primaryType.Type == KnownPrimaryType.UnixTime || primaryType.Type == KnownPrimaryType.Uuid)); } diff --git a/AutoRest/Generators/CSharp/CSharp/TemplateModels/MethodTemplateModel.cs b/AutoRest/Generators/CSharp/CSharp/TemplateModels/MethodTemplateModel.cs index cc44708181..d4a380df27 100644 --- a/AutoRest/Generators/CSharp/CSharp/TemplateModels/MethodTemplateModel.cs +++ b/AutoRest/Generators/CSharp/CSharp/TemplateModels/MethodTemplateModel.cs @@ -351,6 +351,14 @@ public string GetSerializationSettingsReference(IType serializationType) { return "new Base64UrlJsonConverter()"; } + else if (serializationType.IsPrimaryType(KnownPrimaryType.UnixTime) || + (sequenceType != null && sequenceType.ElementType is PrimaryType + && ((PrimaryType)sequenceType.ElementType).Type == KnownPrimaryType.UnixTime) || + (dictionaryType != null && dictionaryType.ValueType is PrimaryType + && ((PrimaryType)dictionaryType.ValueType).Type == KnownPrimaryType.UnixTime)) + { + return "new UnixTimeJsonConverter()"; + } return ClientReference + ".SerializationSettings"; } @@ -371,7 +379,7 @@ public string GetDeserializationSettingsReference(IType deserializationType) { return "new DateJsonConverter()"; } - if (deserializationType.IsPrimaryType(KnownPrimaryType.Base64Url) || + else if (deserializationType.IsPrimaryType(KnownPrimaryType.Base64Url) || (sequenceType != null && sequenceType.ElementType is PrimaryType && ((PrimaryType)sequenceType.ElementType).Type == KnownPrimaryType.Base64Url) || (dictionaryType != null && dictionaryType.ValueType is PrimaryType @@ -379,6 +387,14 @@ public string GetDeserializationSettingsReference(IType deserializationType) { return "new Base64UrlJsonConverter()"; } + else if (deserializationType.IsPrimaryType(KnownPrimaryType.UnixTime) || + (sequenceType != null && sequenceType.ElementType is PrimaryType + && ((PrimaryType)sequenceType.ElementType).Type == KnownPrimaryType.UnixTime) || + (dictionaryType != null && dictionaryType.ValueType is PrimaryType + && ((PrimaryType)dictionaryType.ValueType).Type == KnownPrimaryType.UnixTime)) + { + return "new UnixTimeJsonConverter()"; + } return ClientReference + ".DeserializationSettings"; } diff --git a/AutoRest/Generators/CSharp/CSharp/Templates/ModelTemplate.cshtml b/AutoRest/Generators/CSharp/CSharp/Templates/ModelTemplate.cshtml index 2bcf9676f0..942e67ef80 100644 --- a/AutoRest/Generators/CSharp/CSharp/Templates/ModelTemplate.cshtml +++ b/AutoRest/Generators/CSharp/CSharp/Templates/ModelTemplate.cshtml @@ -123,6 +123,10 @@ namespace @(Settings.Namespace).Models { @:[JsonConverter(typeof(Base64UrlJsonConverter))] } + if (property.Type.IsPrimaryType(KnownPrimaryType.UnixTime)) + { + @:[JsonConverter(typeof(UnixTimeJsonConverter))] + } @:[JsonProperty(PropertyName = "@property.SerializedName")] @:public @property.Type.Name @property.Name { get; @(property.IsReadOnly ? "private " : "")set; } @EmptyLine @@ -145,6 +149,10 @@ namespace @(Settings.Namespace).Models { @:[JsonConverter(typeof(Base64UrlJsonConverter))] } + if (property.Type.IsPrimaryType(KnownPrimaryType.UnixTime)) + { + @:[JsonConverter(typeof(UnixTimeJsonConverter))] + } @:[JsonProperty(PropertyName = "@property.SerializedName")] @:public static @property.Type.Name @property.Name { get; private set; } @EmptyLine diff --git a/AutoRest/Generators/Java/Java/TypeModels/PrimaryTypeModel.cs b/AutoRest/Generators/Java/Java/TypeModels/PrimaryTypeModel.cs index 2d5a2fad78..d6990c79ff 100644 --- a/AutoRest/Generators/Java/Java/TypeModels/PrimaryTypeModel.cs +++ b/AutoRest/Generators/Java/Java/TypeModels/PrimaryTypeModel.cs @@ -202,6 +202,10 @@ private void Initialize(PrimaryType primaryType) Name = "Period"; _imports.Add("org.joda.time.Period"); } + else if (primaryType.Type == KnownPrimaryType.UnixTime) + { + Name = "long"; + } else if (primaryType.Type == KnownPrimaryType.Uuid) { Name = "UUID"; diff --git a/AutoRest/Generators/NodeJS/NodeJS/NodeJsCodeNamer.cs b/AutoRest/Generators/NodeJS/NodeJS/NodeJsCodeNamer.cs index 53ac858681..d2f43a402f 100644 --- a/AutoRest/Generators/NodeJS/NodeJS/NodeJsCodeNamer.cs +++ b/AutoRest/Generators/NodeJS/NodeJS/NodeJsCodeNamer.cs @@ -393,6 +393,10 @@ private static IType NormalizePrimaryType(PrimaryType primaryType) { primaryType.Name = "moment.duration"; } + else if (primaryType.Type == KnownPrimaryType.UnixTime) + { + primaryType.Name = "Number"; + } else if (primaryType.Type == KnownPrimaryType.Uuid) { primaryType.Name = "Uuid"; diff --git a/AutoRest/Generators/Python/Python/PythonCodeNamer.cs b/AutoRest/Generators/Python/Python/PythonCodeNamer.cs index 4aebfb6378..11ae0801ac 100644 --- a/AutoRest/Generators/Python/Python/PythonCodeNamer.cs +++ b/AutoRest/Generators/Python/Python/PythonCodeNamer.cs @@ -376,6 +376,10 @@ private static IType NormalizePrimaryType(PrimaryType primaryType) { primaryType.Name = "Decimal"; } + else if (primaryType.Type == KnownPrimaryType.UnixTime) + { + primaryType.Name = "long"; + } else if (primaryType.Type == KnownPrimaryType.Object) // Revisit here { primaryType.Name = "object"; diff --git a/AutoRest/Generators/Ruby/Ruby/RubyCodeNamer.cs b/AutoRest/Generators/Ruby/Ruby/RubyCodeNamer.cs index bcb90309c6..c40423ee1b 100644 --- a/AutoRest/Generators/Ruby/Ruby/RubyCodeNamer.cs +++ b/AutoRest/Generators/Ruby/Ruby/RubyCodeNamer.cs @@ -372,6 +372,10 @@ private IType NormalizePrimaryType(PrimaryType primaryType) { primaryType.Name = "Duration"; } + else if (primaryType.Type == KnownPrimaryType.UnixTime) + { + primaryType.Name = "Bignum"; + } else if (primaryType.Type == KnownPrimaryType.Object) { primaryType.Name = "Object"; diff --git a/AutoRest/Modelers/Swagger/Model/SwaggerObject.cs b/AutoRest/Modelers/Swagger/Model/SwaggerObject.cs index 2ca86ef10d..02bfb0d23b 100644 --- a/AutoRest/Modelers/Swagger/Model/SwaggerObject.cs +++ b/AutoRest/Modelers/Swagger/Model/SwaggerObject.cs @@ -132,6 +132,10 @@ public PrimaryType ToType() { return new PrimaryType(KnownPrimaryType.Long); } + if (string.Equals("unixtime", Format, StringComparison.OrdinalIgnoreCase)) + { + return new PrimaryType(KnownPrimaryType.UnixTime); + } return new PrimaryType(KnownPrimaryType.Int); case DataType.Boolean: return new PrimaryType(KnownPrimaryType.Boolean); diff --git a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime/Serialization/UnixTimeJsonConverter.cs b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime/Serialization/UnixTimeJsonConverter.cs new file mode 100644 index 0000000000..8f6283b623 --- /dev/null +++ b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime/Serialization/UnixTimeJsonConverter.cs @@ -0,0 +1,76 @@ +// 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 Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Rest.Serialization +{ + public class UnixTimeJsonConverter : JsonConverter + { + public static readonly DateTime EpochDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + /// + /// Converts a byte array to a Base64Url encoded string + /// + /// The byte array to convert + /// The Base64Url encoded form of the input + private static long? ToUnixTime(DateTime dateTime) + { + return (long?)dateTime.Subtract(EpochDate).TotalSeconds; + } + + /// + /// Converts a Base64Url encoded string to a byte array + /// + /// The Base64Url encoded string + /// The byte array represented by the enconded string + private static DateTime FromUnixTime(long? seconds) + { + if (seconds.HasValue) + { + return EpochDate.AddSeconds(seconds.Value); + } + return EpochDate; + } + + public override bool CanConvert(Type objectType) + { + if (objectType == typeof(DateTime)) + return true; + + return false; + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (objectType != typeof(DateTime)) + { + return serializer.Deserialize(reader, objectType); + } + else + { + var value = serializer.Deserialize(reader); + if (value.HasValue) + { + return FromUnixTime(value); + } + } + + return null; + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + if (value.GetType() != typeof(DateTime)) + { + JToken.FromObject(value).WriteTo(writer); + } + else + { + JToken.FromObject(ToUnixTime((DateTime)value)).WriteTo(writer); + } + } + } +} \ No newline at end of file