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 @@ -33,3 +33,4 @@
- Implement `xsd:float` codec
- Implement `xsd:unsignedInt` codec
- Implement `xsd:integer` codec
- Implement `xsd:negativeInteger` codec
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ This library aims to support the following XSD 1.1 built-in datatypes that are c
| `xsd:float` | ✅ | ✅ | `double` | `dart:core` |
| `xsd:integer` | ✅ | ✅ | `BigInt` | `dart:core` |
| `xsd:nonPositiveInteger` | ✅ | ✅ | `BigInt` | `dart:core` |
| `xsd:negativeInteger` | ✅ | | `BigInt` | `dart:core` |
| `xsd:negativeInteger` | ✅ | | `BigInt` | `dart:core` |
| `xsd:long` | ✅ | ✅ | `BigInt` | `dart:core` |
| `xsd:int` | ✅ | ✅ | `int` | `dart:core` |
| `xsd:short` | ✅ | ✅ | `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 @@ -30,3 +30,4 @@ export 'double/double_codec.dart';
export 'float/float_codec.dart';
export 'integer/integer_codec.dart';
export 'unsigned_int/unsigned_int_codec.dart';
export 'negative_integer/negative_integer_codec.dart';
18 changes: 18 additions & 0 deletions lib/src/codecs/negative_integer/negative_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/negative_integer/negative_integer_decoder.dart';
import 'package:xsd/src/codecs/negative_integer/negative_integer_encoder.dart';

/// A codec for xsd:negativeInteger.
///
/// Converts between a string representation of a negative integer and a
/// [BigInt].
class XsdNegativeIntegerCodec extends Codec<BigInt, String> {
const XsdNegativeIntegerCodec();

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

@override
Converter<BigInt, String> get encoder => const XsdNegativeIntegerEncoder();
}
32 changes: 32 additions & 0 deletions lib/src/codecs/negative_integer/negative_integer_decoder.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'dart:convert';

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

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

static final BigInt _maxValue = BigInt.from(-1);

@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;
}
}
18 changes: 18 additions & 0 deletions lib/src/codecs/negative_integer/negative_integer_encoder.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'dart:convert';

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

static final BigInt _maxValue = BigInt.from(-1);

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

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

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

test('should encode valid negative integer', () {
expect(codec.encode(BigInt.from(-1)), '-1');
expect(codec.encode(BigInt.from(-123)), '-123');
});

test('should decode valid negative integer', () {
expect(codec.decode('-1'), BigInt.from(-1));
expect(codec.decode('-123'), BigInt.from(-123));
expect(codec.decode(' -123 '), BigInt.from(-123));
});

test('should throw on invalid negative integer', () {
expect(() => codec.decode('0'), throwsFormatException);
expect(() => codec.decode('1'), throwsFormatException);
expect(() => codec.decode('abc'), throwsFormatException);
expect(() => codec.decode(''), throwsFormatException);
expect(() => codec.decode(' '), throwsFormatException);
expect(() => codec.encode(BigInt.zero), throwsFormatException);
expect(() => codec.encode(BigInt.one), throwsFormatException);
});
});
}