1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//! This simple tool reads potential ISINs from stdin, one per line, and parses them. It will panic
//! if any fail to parse. This can be used as a simple bulk test of a file of purported ISINs to
//! ensure there are no malformed entries present. If you have a known-good file of valid ISINs, it
//! can be used to validate this crate considers them valid.
//!
//! As part of the `isin` crate's initial validation, this tool was run on a file of 5,273,047
//! unique ISINs produced by processing a file mapping LEIs to ISINs obtained from GLEIF. The
//! [GLEIF file](https://www.gleif.org/en/lei-data/lei-mapping/download-isin-to-lei-relationship-files)
//! is very large (the version from 2021-02-09 was about 170MB). Here are a few example records from
//! the beginning of the file (the first line is the header row with field names):
//!
//! ```sh
//! head -11 ISIN_LEI_20210209.csv | tail -10
//! S6XOOCT0IEG5ABCC6L87,US3137A3KN83
//! XZYUUT6IYN31D9K77X08,DE000JC86RE7
//! 378900EB75D7D2C73323,ZAG000163650
//! 254900EDYO1UYWLWP146,US12613N2027
//! 549300DRQQI75D2JP341,US05531GQN42
//! S6XOOCT0IEG5ABCC6L87,US31394GAX16
//! K6Q0W1PS1L1O4IQL9C32,DE000SLA61X8
//! 529900W18LQJJN6SJ336,DE000CL78501
//! S6XOOCT0IEG5ABCC6L87,US3137ASGH19
//! G5GSEF7VJP5I7OUK5573,US06741RAP64
//! ```
//!
//! You can use a command like this to subset just the ISINs:
//!
//! ```sh
//! sed -e 's/^.*,//' ISIN_LEI_20210209.csv \
//! | grep -v '^ISIN$' \
//! | sort | uniq | gzip -9 \
//! > isins.txt.gz
//! ```
//!
//! This file was about 16.6MB for the version tested and contained over 5.2 million ISINs.
//!
//! Having produced the file, it is now possible to run it through this tool. From the source
//! directory of this crate, you can run:
//!
//! ```sh
//! gzcat isins.txt.gz | cargo run isin-tool
//! ```
//!
//! And, output will be something like this:
//!
//! ```text
//! Read 5273047 values; 5273047 were valid ISINs and 0 were not.
//! ```
//!
//! If no bad values were found, the tool will exit with zero status, else non-zero.
//!
//! ## Fix mode
//!
//! If you run with argument `--fix`, then any input ISINs that are only wrong due to incorrect
//! _Check Digit_ will be fixed. In this mode, every good and every fixable input ISIN is printed
//! to standard output.
use env;
use io;
use *;
use from_utf8_unchecked;