Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added serialization interfaces for DateOnly, TimeOnly, Guid and Duration #8

Merged
merged 14 commits into from
Feb 14, 2024
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/kiota_abstractions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@ import 'dart:typed_data';

import 'package:kiota_abstractions/src/case_insensitive_map.dart';
import 'package:std_uritemplate/std_uritemplate.dart';
import 'package:uuid/uuid.dart';

part 'src/api_client_builder.dart';
part 'src/base_request_builder.dart';
part 'src/date_only.dart';
part 'src/error_mappings.dart';
part 'src/extensions/date_only_extensions.dart';
part 'src/extensions/map_extensions.dart';
part 'src/extensions/request_information_extensions.dart';
part 'src/extensions/time_only_extensions.dart';
part 'src/http_headers.dart';
part 'src/http_method.dart';
part 'src/multipart_body.dart';
Expand All @@ -41,4 +45,5 @@ part 'src/serialization/parse_node_proxy_factory.dart';
part 'src/serialization/serialization_writer.dart';
part 'src/serialization/serialization_writer_factory.dart';
part 'src/serialization/serialization_writer_factory_registry.dart';
part 'src/time_only.dart';
part 'src/serialization/serialization_writer_proxy_factory.dart';
67 changes: 67 additions & 0 deletions lib/src/date_only.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
part of '../kiota_abstractions.dart';

/// Interface for a date only object.
///
/// This interface provides an abstraction layer over date only objects.
/// It is used to represent date only values in a serialization format agnostic
/// way.
///
/// It can only be used to represent a date in the Gregorian calendar.
abstract class DateOnly {
/// Extracts the date part of a [DateTime] and creates an object implementing
/// [DateOnly].
factory DateOnly.fromDateTime(DateTime dateTime) {
andrueastman marked this conversation as resolved.
Show resolved Hide resolved
return _DateOnlyImpl(
day: dateTime.day,
month: dateTime.month,
year: dateTime.year,
);
}

/// This factory uses the [DateTime.parse] method to create an object
/// implementing [DateOnly].
factory DateOnly.fromDateTimeString(String dateTimeString) {
final date = DateTime.parse(dateTimeString);

return DateOnly.fromDateTime(date);
}

/// Creates an object implementing [DateOnly] from the provided components.
factory DateOnly.fromComponents(
int year, [
int month = 1,
int day = 1,
]) {
return _DateOnlyImpl(
day: day,
month: month,
year: year,
);
}

/// Gets the year of the date.
int get year;

/// Gets the month of the date.
int get month;

/// Gets the day of the date.
int get day;
}

class _DateOnlyImpl implements DateOnly {
baywet marked this conversation as resolved.
Show resolved Hide resolved
_DateOnlyImpl({
required this.day,
required this.month,
required this.year,
});

@override
final int day;

@override
final int month;

@override
final int year;
}
25 changes: 25 additions & 0 deletions lib/src/extensions/date_only_extensions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
part of '../../kiota_abstractions.dart';

/// Extension methods for [DateOnly].
extension DateOnlyExtensions on DateOnly {
/// Converts the [DateOnly] to a [DateTime].
DateTime toDateTime() => DateTime(year, month, day);

/// Combines the [DateOnly] with the given [TimeOnly].
DateTime combine(TimeOnly time) {
return DateTime(
year,
month,
day,
time.hours,
time.minutes,
time.seconds,
time.milliseconds,
);
}

/// Converts the [DateOnly] to a string in the format `yyyy-MM-dd`.
String toRfc3339String() {
return '${year.toString().padLeft(4, '0')}-${month.toString().padLeft(2, '0')}-${day.toString().padLeft(2, '0')}';
}
}
46 changes: 46 additions & 0 deletions lib/src/extensions/time_only_extensions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
part of '../../kiota_abstractions.dart';

/// Extension methods for [TimeOnly].
extension TimeOnlyExtensions on TimeOnly {
/// Converts the [TimeOnly] to a [DateTime].
DateTime toDateTime(
int year, [
int month = 1,
int day = 1,
]) =>
DateTime(
year,
month,
day,
hours,
minutes,
seconds,
milliseconds,
);

/// Combines the [TimeOnly] with the given [DateOnly].
DateTime combine(DateOnly date) {
return DateTime(
date.year,
date.month,
date.day,
hours,
minutes,
seconds,
milliseconds,
);
}

/// Converts the [TimeOnly] to a string in the format `HH:mm:ss` or
/// `HH:mm:ss.SSS` if milliseconds are present.
String toRfc3339String() {
final String fractionString;
if (milliseconds > 0) {
fractionString = '.${milliseconds.toString().padLeft(3, '0')}';
} else {
fractionString = '';
}

return '${hours.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}$fractionString';
}
}
12 changes: 12 additions & 0 deletions lib/src/serialization/parse_node.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,21 @@ abstract class ParseNode {
/// Gets the double value of the node.
double? getDoubleValue();

/// Gets the [UuidValue] value of the node.
UuidValue? getGuidValue();

/// Gets the [DateTime] value of the node.
DateTime? getDateTimeValue();

/// Gets the [DateOnly] value of the node.
DateOnly? getDateOnlyValue();

/// Gets the [TimeOnly] value of the node.
TimeOnly? getTimeOnlyValue();

/// Gets the [Duration] value of the node.
Duration? getDurationValue();

/// Gets the collection of primitive values of the node.
Iterable<T> getCollectionOfPrimitiveValues<T>();

Expand Down
75 changes: 75 additions & 0 deletions lib/src/time_only.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
part of '../kiota_abstractions.dart';

/// Interface for a time only object that represents a time of day.
///
/// This interface provides an abstraction layer over time only objects.
/// It is used to represent time only values in a serialization format agnostic
/// way.
abstract class TimeOnly {
/// Extracts the time part of a [DateTime] and creates an object implementing
/// [TimeOnly].
factory TimeOnly.fromDateTime(DateTime dateTime) {
return _TimeOnlyImpl(
hours: dateTime.hour,
minutes: dateTime.minute,
seconds: dateTime.second,
milliseconds: dateTime.millisecond,
);
}

/// This factory uses the [DateTime.parse] method to create an object
/// implementing [TimeOnly].
factory TimeOnly.fromDateTimeString(String dateTimeString) {
final dateTime = DateTime.parse('2024-01-01 $dateTimeString');
ricardoboss marked this conversation as resolved.
Show resolved Hide resolved

return TimeOnly.fromDateTime(dateTime);
}

/// Constructs an object implementing [TimeOnly] from the provided components.
factory TimeOnly.fromComponents(
int hours,
int minutes, [
int seconds = 0,
int milliseconds = 0,
]) {
return _TimeOnlyImpl(
hours: hours,
minutes: minutes,
seconds: seconds,
milliseconds: milliseconds,
);
}

/// Gets the hours of the time.
int get hours;

/// Gets the minutes of the time.
int get minutes;

/// Gets the seconds of the time.
int get seconds;

/// Gets the milliseconds of the time.
int get milliseconds;
}

class _TimeOnlyImpl implements TimeOnly {
_TimeOnlyImpl({
required this.hours,
required this.minutes,
required this.seconds,
required this.milliseconds,
});

@override
final int hours;

@override
final int minutes;

@override
final int seconds;

@override
final int milliseconds;
}
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ environment:

dependencies:
std_uritemplate: ^0.0.52
uuid: ^4.3.3

dev_dependencies:
strict: ^2.0.0
Expand Down
40 changes: 40 additions & 0 deletions test/date_only_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// ignore_for_file: avoid_redundant_argument_values

import 'package:kiota_abstractions/kiota_abstractions.dart';
import 'package:test/test.dart';

void main() {
group('DateOnly', () {
test('fromDateTimeString and toRfc3339String', () {
expect(
DateOnly.fromDateTimeString('2021-01-01').toRfc3339String(),
'2021-01-01',
);
});

test('round trip', () {
final fromString = DateOnly.fromDateTimeString('2021-01-01');
final toString = fromString.toRfc3339String();
expect(toString, '2021-01-01');

final roundTrip = DateOnly.fromDateTimeString(toString);
final roundTripString = roundTrip.toRfc3339String();
expect(roundTripString, '2021-01-01');
});

test('fromDateTime', () {
final dateTime = DateTime(2024, 2, 3, 12, 34, 56);
expect(
DateOnly.fromDateTime(dateTime).toRfc3339String(),
'2024-02-03',
);
});

test('fromComponents', () {
expect(
DateOnly.fromComponents(2021, 1, 1).toRfc3339String(),
'2021-01-01',
);
});
});
}
54 changes: 54 additions & 0 deletions test/time_only_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import 'package:kiota_abstractions/kiota_abstractions.dart';
import 'package:test/test.dart';

void main() {
group('TimeOnly', () {
test('fromDateTimeString and toRfc3339String', () {
expect(
TimeOnly.fromDateTimeString('12:34:56').toRfc3339String(),
'12:34:56',
);
expect(
TimeOnly.fromDateTimeString('12:34').toRfc3339String(),
'12:34:00',
);
expect(
TimeOnly.fromDateTimeString('12').toRfc3339String(),
'12:00:00',
);
});

test('round trip', () {
final fromString = TimeOnly.fromDateTimeString('12:34:56.789');
final toString = fromString.toRfc3339String();
expect(toString, '12:34:56.789');

final roundTrip = TimeOnly.fromDateTimeString(toString);
final roundTripString = roundTrip.toRfc3339String();
expect(roundTripString, '12:34:56.789');
});

test('fromDateTime', () {
final dateTime = DateTime(2021, 1, 1, 12, 34, 56);
expect(
TimeOnly.fromDateTime(dateTime).toRfc3339String(),
'12:34:56',
);
});

test('fromComponents', () {
expect(
TimeOnly.fromComponents(12, 34, 56, 789).toRfc3339String(),
'12:34:56.789',
);
expect(
TimeOnly.fromComponents(12, 34, 56).toRfc3339String(),
'12:34:56',
);
expect(
TimeOnly.fromComponents(12, 34).toRfc3339String(),
'12:34:00',
);
});
});
}