Skip to content

Commit

Permalink
Add support for Unix time (#419)
Browse files Browse the repository at this point in the history
Generate internal type timeUnix for marshalling and unmarshalling time
in Unix format.
  • Loading branch information
jhendrixMSFT authored Jun 9, 2020
1 parent 801eae1 commit 403d35f
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 20 deletions.
18 changes: 11 additions & 7 deletions src/generator/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,13 @@ function formatParamValue(param: Parameter, imports: ImportManager): string {
}
return `${paramName}.Format(${format})`;
case SchemaType.Duration:
case SchemaType.UnixTime:
if (param.required !== true && paramName[0] === '*') {
// remove the dereference
paramName = paramName.substr(1);
}
return `${paramName}.String()`;
case SchemaType.UnixTime:
return `timeUnix(${paramName}).String()`;
case SchemaType.Uri:
imports.add('net/url');
if (param.required !== true && paramName[0] === '*') {
Expand Down Expand Up @@ -564,11 +565,11 @@ function createProtocolRequest(client: string, op: Operation, imports: ImportMan
addr = '';
}
body = `wrapper{${fieldName}: ${addr}${body}}`;
} else if (bodyParam!.schema.type === SchemaType.DateTime && (<DateTimeSchema>bodyParam!.schema).format === 'date-time-rfc1123') {
} else if ((bodyParam!.schema.type === SchemaType.DateTime && (<DateTimeSchema>bodyParam!.schema).format === 'date-time-rfc1123') || bodyParam!.schema.type === SchemaType.UnixTime) {
// wrap the body in the custom RFC1123 type
text += `\taux := ${bodyParam!.schema.language.go!.internalTimeType}(${body})\n`;
body = 'aux';
} else if (isArrayOfRFC1123(bodyParam!.schema)) {
} else if (isArrayOfTimesForMarshalling(bodyParam!.schema)) {
const timeType = (<ArraySchema>bodyParam!.schema).elementType.language.go!.internalTimeType;
text += `\taux := make([]${timeType}, len(${body}), len(${body}))\n`;
text += `\tfor i := 0; i < len(${body}); i++ {\n`;
Expand Down Expand Up @@ -616,12 +617,15 @@ function getMediaFormat(schema: Schema, mediaType: 'JSON' | 'XML', param: string
return `${marshaller}(${param}${format})`;
}

function isArrayOfRFC1123(schema: Schema): boolean {
function isArrayOfTimesForMarshalling(schema: Schema): boolean {
if (schema.type !== SchemaType.Array) {
return false;
}
const arraySchema = <ArraySchema>schema;
const arrayElem = <Schema>arraySchema.elementType;
if (arrayElem.type === SchemaType.UnixTime) {
return true;
}
if (arrayElem.type !== SchemaType.DateTime) {
return false;
}
Expand Down Expand Up @@ -676,7 +680,7 @@ function createProtocolResponse(client: string, op: Operation, imports: ImportMa
text += `\treturn resp.Response, nil\n`;
text += '}\n\n';
return text;
} else if (firstResp.schema.type === SchemaType.DateTime) {
} else if (firstResp.schema.type === SchemaType.DateTime || firstResp.schema.type === SchemaType.UnixTime) {
// use the designated time type for unmarshalling
text += `\tvar aux *${firstResp.schema.language.go!.internalTimeType}\n`;
text += `\terr := resp.UnmarshalAs${getMediaType(firstResp.protocol)}(&aux)\n`;
Expand Down Expand Up @@ -806,7 +810,7 @@ function isArrayOfDateTime(schema: Schema): boolean {
}
const arraySchema = <ArraySchema>schema;
const arrayElem = <Schema>arraySchema.elementType;
return arrayElem.type === SchemaType.DateTime;
return arrayElem.type === SchemaType.DateTime || arrayElem.type === SchemaType.UnixTime;
}

function isMapOfDateTime(schema: Schema): boolean {
Expand All @@ -815,7 +819,7 @@ function isMapOfDateTime(schema: Schema): boolean {
}
const dictSchema = <DictionarySchema>schema;
const dictElem = <Schema>dictSchema.elementType;
return dictElem.type === SchemaType.DateTime;
return dictElem.type === SchemaType.DateTime || dictElem.type === SchemaType.UnixTime;
}

function createInterfaceDefinition(group: OperationGroup, imports: ImportManager): string {
Expand Down
33 changes: 33 additions & 0 deletions src/generator/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ export async function generateTimeHelpers(session: Session<CodeModel>): Promise<
if (session.model.language.go!.hasTimeRFC3339) {
content.push(new Content('time_rfc3339', generateRFC3339Helper(preamble)));
}
if (session.model.language.go!.hasUnixTime) {
content.push(new Content('time_unix', generateUnixTimeHelper(preamble)));
}
return content;
}

Expand Down Expand Up @@ -124,3 +127,33 @@ func (t *timeRFC3339) Parse(layout, value string) error {
}
`;
}

function generateUnixTimeHelper(preamble: string): string {
return `${preamble}
import (
"encoding/json"
"fmt"
"time"
)
type timeUnix time.Time
func (t timeUnix) MarshalJSON() ([]byte, error) {
return json.Marshal(time.Time(t).Unix())
}
func (t *timeUnix) UnmarshalJSON(data []byte) error {
var seconds int64
if err := json.Unmarshal(data, &seconds); err != nil {
return err
}
*t = timeUnix(time.Unix(seconds, 0))
return nil
}
func (t timeUnix) String() string {
return fmt.Sprintf("%d", time.Time(t).Unix())
}
`;
}
5 changes: 5 additions & 0 deletions src/transform/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,12 @@ function schemaTypeToGoType(codeModel: CodeModel, schema: Schema, inBody: boolea
}
}
case SchemaType.Date:
return 'time.Time';
case SchemaType.UnixTime:
codeModel.language.go!.hasUnixTime = true;
if (inBody) {
schema.language.go!.internalTimeType = 'timeUnix';
}
return 'time.Time';
case SchemaType.Dictionary:
const dictSchema = <DictionarySchema>schema;
Expand Down
18 changes: 11 additions & 7 deletions test/autorest/generated/integergroup/int.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions test/autorest/generated/integergroup/time_unix.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test/autorest/generated/urlgroup/paths.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions test/autorest/generated/urlgroup/time_unix.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions test/autorest/integergroup/integergroup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,14 @@ func TestIntGetUnderflowInt64(t *testing.T) {
}

func TestIntGetUnixTime(t *testing.T) {
t.Skip()
client := getIntegerOperations(t)
result, err := client.GetUnixTime(context.Background())
if err != nil {
t.Fatalf("GetUnixTime: %v", err)
}
t1 := time.Unix(1460505600, 0)
helpers.VerifyStatusCode(t, result.RawResponse, http.StatusOK)
helpers.DeepEqualOrFatal(t, result.Value, t1)
helpers.DeepEqualOrFatal(t, result.Value, &t1)
}

func TestIntPutMax32(t *testing.T) {
Expand Down Expand Up @@ -156,7 +155,6 @@ func TestIntPutMin64(t *testing.T) {
}

func TestIntPutUnixTimeDate(t *testing.T) {
t.Skip()
client := getIntegerOperations(t)
t1 := time.Unix(1460505600, 0)
result, err := client.PutUnixTimeDate(context.Background(), t1)
Expand Down
2 changes: 0 additions & 2 deletions test/autorest/urlgroup/paths_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,7 @@ func TestPathsStringUnicode(t *testing.T) {
helpers.VerifyStatusCode(t, result, http.StatusOK)
}

// TODO verify why this is not working
func TestPathsUnixTimeURL(t *testing.T) {
t.Skip()
client := getPathsOperations(t)
d, err := time.Parse("2006-01-02", "2016-04-13")
if err != nil {
Expand Down

0 comments on commit 403d35f

Please sign in to comment.