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

Bring newest changes from main to nullsafety branch #10

Open
wants to merge 28 commits into
base: nullsafety
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
39a01e9
Add support for 2-character manufacturer codes in the WMI
pmundt May 29, 2021
1010c47
Update stable release to 0.1.4
pmundt May 29, 2021
235f9cb
Reduce dart SDK constraints for unsound null safety
pmundt May 29, 2021
3740e6a
Revert "null safety migration" for stable release
pmundt May 29, 2021
7635210
Match min dart SDK constraint for stable release
pmundt May 29, 2021
2ce1ced
Add .vscode to .gitignore
pmundt Aug 25, 2021
dc082f1
Expose NHTSA API accessors
pmundt Aug 26, 2021
00bb611
Update Travis CI badge link
pmundt Aug 26, 2021
717aaf6
Bump up dependency versions
pmundt Aug 26, 2021
9d2eb7c
Merge branch 'nullsafety' into master
BellRampion Dec 2, 2022
6ea3d42
Nullsafety compliant
BellRampion Dec 2, 2022
2357c09
Added as submodule
BellRampion Dec 7, 2022
47b930f
Merge pull request #1 from Stemco/nullsafetyUpdate
BellRampion Dec 7, 2022
58d8593
Added typecasting
BellRampion Dec 7, 2022
6a4d02a
Fixed VIN decoder to never return empty string
BellRampion Dec 21, 2022
9705d72
Updated pubspec.yaml
Daniel-Harding Mar 24, 2023
3d20f6e
Linter fixes
BellRampion Mar 30, 2023
2531d20
Fixed linter error
BellRampion Mar 30, 2023
12a80f5
Updated year models to 2000 to 2029
Daniel-Harding Jul 28, 2023
5ed65a2
Merge branch 'master' of https://github.com/Stemco/vin-decoder-dart
Daniel-Harding Jul 28, 2023
6e4c419
Added check for properties
ghananand-shukla-cgi Sep 25, 2023
aa22d7a
Merge pull request #2 from Stemco/vin_gh
Daniel-Harding Sep 25, 2023
36a8d42
fix issue of int conversion
ghananand-shukla-cgi Sep 27, 2023
4adaf26
Merge pull request #3 from Stemco/vin_gh
Daniel-Harding Sep 27, 2023
1965790
Added fuel type search (issue #670)
JosueJovel Dec 20, 2023
bfea38d
Issue #670: refactor fuelMap as a const and handle mismatching cases/…
Nathan-Bianco Mar 19, 2024
009fde5
Added more Fuel types
Daniel-Harding Mar 27, 2024
999e2fa
Added the keyword "Electric" for fuel type 2
Daniel-Harding May 16, 2024
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
# Remove the following pattern if you wish to check in your lock file
pubspec.lock

# IntelliJ
# IntelliJ / IDEs
*.iml
.idea/
.vscode/

# Conventional directory for build outputs
build/
Expand Down
3 changes: 2 additions & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
#
# Name/Organization <email address>

Adaptant Labs <[email protected]>
Adaptant Labs <[email protected]>
Stemco
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
## 0.2.1
- Migrated completely to nullsafety

## 0.2.0

- Expose helpers for querying NHTSA DB and accessing extended vehicle information (requested by @ride4sun, issue #8)

## 0.1.4+1

- Revert null-safety changes from stable release to satisfy SDK constraints

## 0.1.4

- Support VINs with 2-character manufacturer IDs in their WMI (reported by @huangkaichang, issue #7)
- Fix Uri parsing for NHTSA DB REST API
## 0.2.1-nullsafety

- Support VINs with 2-character manufacturer IDs in their WMI (reported by @huangkaichang, issue #7)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
vin-decoder-dart
================

[![Build Status](https://travis-ci.com/adaptant-labs/vin-decoder-dart.svg?branch=master)](https://travis-ci.com/adaptant-labs/vin-decoder-dart#)
[![Build Status](https://travis-ci.com/adaptant-labs/vin-decoder-dart.svg?branch=master)](https://app.travis-ci.com/github/adaptant-labs/vin-decoder-dart)
[![Pub](https://img.shields.io/pub/v/vin_decoder.svg)](https://pub.dartlang.org/packages/vin_decoder)

A VIN decoding, validation, and generation library for Dart.
Expand Down
13 changes: 10 additions & 3 deletions example/vin_decoder_example.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import 'package:vin_decoder/vin_decoder.dart';
import 'package:custom_vin_decoder/nhtsa.dart';
import 'package:custom_vin_decoder/vin_decoder.dart';

void main() async {
var vin = VIN(number: 'WP0ZZZ99ZTS392124', extended: true);
var vin = VIN(vin: 'WP0ZZZ99ZTS392124', extended: true);

print('WMI: ${vin.wmi}');
print('VDS: ${vin.vds}');
Expand All @@ -10,7 +11,7 @@ void main() async {
print("Model year is " + vin.modelYear());
print("Serial number is " + vin.serialNumber());
print("Assembly plant is " + vin.assemblyPlant());
print("Manufacturer is " + vin.getManufacturer()!);
print("Manufacturer is " + (vin.getManufacturer() ?? ""));
print("Year is " + vin.getYear().toString());
print("Region is " + vin.getRegion());
print("VIN string is " + vin.toString());
Expand All @@ -25,6 +26,12 @@ void main() async {
var type = await vin.getVehicleTypeAsync();
print("Type is ${type}");

var info = await NHTSA.decodeVin(vin.number);
print('Plant Country is ' + (info?.value('Plant Country') ?? ""));

var values = await NHTSA.decodeVinValues(vin.number);
print('Manufacturer from NHTSA DB is ' + values?['Manufacturer']);

var generated = VINGenerator().generate();
print('Randomly Generated VIN is ${generated}');
}
4 changes: 4 additions & 0 deletions lib/nhtsa.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/// Support for querying NHTSA database by VIN.
library nhtsa;

export 'src/nhtsa_model.dart';
153 changes: 92 additions & 61 deletions lib/src/nhtsa_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,71 @@ import 'package:basic_utils/basic_utils.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

// NHTSA Results not relevant for a specific vehicle can be either null or N/A
const String _RESULT_NOT_APPLICABLE = 'Not Applicable';

// ignore: avoid_classes_with_only_static_members
/// A wrapper for the NHTSA REST API
class NHTSA {
static const String _uriBase = 'https://vpic.nhtsa.dot.gov/api/vehicles';

/// Obtain information about a given [vin] from the NHTSA DB.
static Future<NHTSAVehicleInfo?> decodeVin(String vin) async {
var path = _uriBase + '/DecodeVin/' + vin + '?format=json';
final response = await http.get(Uri.parse(path));

if (response.statusCode == 200) {
return NHTSAVehicleInfo.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
}

return null;
}

/// Obtain a map of key/value pairs containing known values for a given [vin]
static Future<Map<String, dynamic>?> decodeVinValues(String vin) async {
var path = _uriBase + '/DecodeVinValues/' + vin + '?format=json';
final response = await http.get(Uri.parse(path));

// The DecodeVinValues endpoint returns a single Results object with all
// variables and values as an array of encapsulated key/value pairs.
// Manually unpack this in order to provide the caller a populated Dart map.
if (response.statusCode == 200) {
final Map<String, dynamic> data = jsonDecode(response.body) as Map<String, dynamic>;
final Map<String, dynamic> map = data['Results'][0] as Map<String, dynamic>;
// Discard empty and not applicable entries from map
map.removeWhere((key, value) =>
value == null || value == _RESULT_NOT_APPLICABLE || value == '');
return map;
}

return null;
}
}

/// The result of a single data point from the NHTSA DB for a specific variable.
class NHTSAResult {
/// The value associated with a given [variable] or [variableId]
String? value;

/// The ID number associated with a given [value]
String? valueId;

/// The variable name
String? variable;

/// The ID number of a given [variable]
int? variableId;

NHTSAResult({this.value, this.valueId, this.variable, this.variableId});
NHTSAResult({required this.value, required this.valueId, required this.variable, required this.variableId});

NHTSAResult.fromJson(Map<String, dynamic> json) {
value = json['Value'];
valueId = json['ValueId'];
variable = json['Variable'];
variableId = json['VariableId'];
/// Create a new [NHTSAResult] instance from a fixed JSON payload
factory NHTSAResult.fromJson(Map<String, dynamic> json) {
return NHTSAResult(
value: json['Value'] as String?,
valueId: json['ValueId'] as String?,
variable: json['Variable'] as String?,
variableId: json['VariableId'] as int?
);
}

@override
Expand All @@ -23,81 +75,60 @@ class NHTSAResult {
}
}

/// Extended vehicle information for a specific VIN obtained from the NHTSA DB.
class NHTSAVehicleInfo {
int? count;
String? message;
String? searchCriteria;
List<NHTSAResult>? results;
int count;
String message;
String searchCriteria;
List<NHTSAResult> results = [];

NHTSAVehicleInfo(
{this.count, this.message, this.searchCriteria, this.results});
{required this.count, required this.message, required this.searchCriteria, required this.results});

NHTSAVehicleInfo.fromJson(Map<String, dynamic> json) {
count = json['Count'];
message = json['Message'];
searchCriteria = json['SearchCriteria'];
/// Create a new [NHTSAVehicleInfo] instance from a fixed JSON payload.
factory NHTSAVehicleInfo.fromJson(Map<String, dynamic> json) {
List<NHTSAResult> results = [];
if (json['Results'] != null) {
results = [];
json['Results'].forEach((v) {
if (v['Value'] != null) {
results!.add(NHTSAResult.fromJson(v));
if (v['Value'] != null &&
v['Value'] != _RESULT_NOT_APPLICABLE &&
v['Value'] != '') {
results.add(NHTSAResult.fromJson(v as Map<String, dynamic>));
}
});
}
return NHTSAVehicleInfo(
count: (json['Count'] as int?) ?? 0,
message: (json['Message'] as String?) ?? "",
searchCriteria:( json['SearchCriteria'] as String?) ?? "",
results: results
);
}

static String normalizeStringValue(String s) {
static String? _normalizeStringValue(String? s) {
if (s == null){
return null;
}
return s.splitMapJoin(' ',
onNonMatch: (m) => StringUtils.capitalize(m.toLowerCase()));
}

ExtendedVehicleInfo toExtendedVehicleInfo() {
final ExtendedVehicleInfo info = ExtendedVehicleInfo();

results!.forEach((f) {
switch (f.variable) {
case "Vehicle Type":
info.vehicleType = normalizeStringValue(f.value!);
break;
case "Make":
info.make = normalizeStringValue(f.value!);
break;
case "Model":
info.model = normalizeStringValue(f.value!);
break;
}
});

return info;
}

@override
String toString() {
return 'NHTSAVehicleInfo[count=$count, message=$message, searchCriteria=$searchCriteria, results=$results]';
/// Lookup the value of a variable by its [variableId] in the NHTSA DB results
String? valueFromId(int? variableId) {
var result = results.singleWhere((e) => e.variableId == variableId,
orElse: () => NHTSAResult(value: null, valueId: null, variable: null, variableId: null));
return _normalizeStringValue(result.value);
}
}

class ExtendedVehicleInfo {
String? make;
String? model;
String? vehicleType;

static Future<ExtendedVehicleInfo?> getExtendedVehicleInfo(String vin) async {
var path = 'https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVin/' +
vin +
'?format=json';
final response = await http.get(Uri.parse(path));

if (response.statusCode == 200) {
var vehicleInfo = NHTSAVehicleInfo.fromJson(jsonDecode(response.body));
return vehicleInfo.toExtendedVehicleInfo();
}

return null;
/// Lookup the value of a named [variable] in the NHTSA DB results
String? value(String variable) {
var result =
results.singleWhere((e) => e.variable == variable, orElse: () => NHTSAResult(value: null, valueId: null, variable: null, variableId: null));
return _normalizeStringValue(result.value);
}

@override
String toString() {
return 'ExtendedVehicleInfo[make=$make, model=$model, vehicleType=$vehicleType]';
return 'NHTSAVehicleInfo[count=$count, message=$message, searchCriteria=$searchCriteria, results=$results]';
}
}
Loading