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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@
- Implement `xsd:gMonth` codec and data type
- Implement `xsd:unsignedShort` data type codec
- Implement `xsd:positiveInteger` data type codec
- Implement `xsd:nonPositiveInteger` data type codec
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ This library aims to support the following XSD 1.1 built-in datatypes that are c
| `xsd:double` | ✅ | ❌ | `double` | `dart:core` |
| `xsd:float` | ✅ | ❌ | `double` | `dart:core` |
| `xsd:integer` | ✅ | ❌ | `BigInt` | `dart:core` |
| `xsd:nonPositiveInteger` | ✅ | ❌ | `BigInt` | `dart:core` |
| `xsd:nonPositiveInteger` | ✅ | ✅ | `BigInt` | `dart:core` |
| `xsd:negativeInteger` | ✅ | ❌ | `BigInt` | `dart:core` |
| `xsd:long` | ✅ | ✅ | `BigInt` | `dart:core` |
| `xsd:int` | ✅ | ✅ | `int` | `dart:core` |
Expand Down
1 change: 1 addition & 0 deletions lib/src/codecs/codecs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ export 'g_year_month/year_month_codec.dart';
export 'g_month/gregorian_month_codec.dart';
export 'unsigned_short/unsigned_short_codec.dart';
export 'positive_integer/positive_integer_codec.dart';
export 'non_positive_integer/non_positive_integer_codec.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'dart:convert';

import 'package:xsd/src/codecs/non_positive_integer/non_positive_integer_decoder.dart';
import 'package:xsd/src/codecs/non_positive_integer/non_positive_integer_encoder.dart';

/// A codec for xsd:nonPositiveInteger.
///
/// Converts between a string representation of a non-positive integer and a
/// [BigInt].
class XsdNonPositiveIntegerCodec extends Codec<BigInt, String> {
const XsdNonPositiveIntegerCodec();

@override
Converter<String, BigInt> get decoder => const XsdNonPositiveIntegerDecoder();

@override
Converter<BigInt, String> get encoder => const XsdNonPositiveIntegerEncoder();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'dart:convert';

import '../../helpers/whitespace.dart';

class XsdNonPositiveIntegerDecoder extends Converter<String, BigInt> {
const XsdNonPositiveIntegerDecoder();

static final BigInt _maxValue = BigInt.zero;

@override
BigInt convert(String input) {
final str = processWhiteSpace(input, Whitespace.collapse);

if (str.isEmpty) {
throw const FormatException('The input string cannot be empty.');
}

final value = BigInt.tryParse(str);

if (value == null) {
throw FormatException('The input "$str" is not a valid integer.');
}

if (value > _maxValue) {
throw FormatException(
'The value "$value" must be less than or equal to $_maxValue.',
);
}

return value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'dart:convert';

class XsdNonPositiveIntegerEncoder extends Converter<BigInt, String> {
const XsdNonPositiveIntegerEncoder();

static final BigInt _maxValue = BigInt.zero;

@override
String convert(BigInt input) {
if (input > _maxValue) {
throw FormatException(
'The value "$input" must be less than or equal to $_maxValue.',
);
}

return input.toString();
}
}
56 changes: 56 additions & 0 deletions test/codecs/non_positive_integer_codec_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import 'package:test/test.dart';
import 'package:xsd/xsd.dart';

void main() {
group('XsdNonPositiveIntegerCodec', () {
const codec = XsdNonPositiveIntegerCodec();

group('decoder', () {
test('should decode a valid non-positive integer string', () {
expect(codec.decode('0'), BigInt.zero);
expect(codec.decode('-1'), BigInt.from(-1));
expect(codec.decode('-123'), BigInt.from(-123));
expect(
codec.decode(
'-9999999999999999999999999999999999999999999999999999999999',
),
BigInt.parse(
'-9999999999999999999999999999999999999999999999999999999999',
),
);
});

test('should throw a FormatException for a positive integer', () {
expect(() => codec.decode('1'), throwsFormatException);
});

test('should throw a FormatException for an empty string', () {
expect(() => codec.decode(''), throwsFormatException);
});

test('should throw a FormatException for a non-integer string', () {
expect(() => codec.decode('abc'), throwsFormatException);
});
});

group('encoder', () {
test('should encode a valid non-positive integer', () {
expect(codec.encode(BigInt.zero), '0');
expect(codec.encode(BigInt.from(-1)), '-1');
expect(codec.encode(BigInt.from(-123)), '-123');
expect(
codec.encode(
BigInt.parse(
'-9999999999999999999999999999999999999999999999999999999999',
),
),
'-9999999999999999999999999999999999999999999999999999999999',
);
});

test('should throw a FormatException for a positive integer', () {
expect(() => codec.encode(BigInt.one), throwsFormatException);
});
});
});
}