diff options
author | Dimitri Sokolyuk <demon@dim13.org> | 2018-07-24 14:35:44 +0200 |
---|---|---|
committer | Dimitri Sokolyuk <demon@dim13.org> | 2018-07-24 14:35:44 +0200 |
commit | 621e49bb465f500cc46d47e39e828cf76d6381d7 (patch) | |
tree | e9d6ed54cfae73209f2b0d9a016ef0b64adf45a6 /vendor/golang.org/x/text/currency/query.go | |
parent | 5b9a4a158b81aa6e94a5a56d0851bea938b87bef (diff) |
update vendor
Diffstat (limited to 'vendor/golang.org/x/text/currency/query.go')
-rw-r--r-- | vendor/golang.org/x/text/currency/query.go | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/vendor/golang.org/x/text/currency/query.go b/vendor/golang.org/x/text/currency/query.go new file mode 100644 index 0000000..7bf9430 --- /dev/null +++ b/vendor/golang.org/x/text/currency/query.go @@ -0,0 +1,152 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package currency + +import ( + "sort" + "time" + + "golang.org/x/text/language" +) + +// QueryIter represents a set of Units. The default set includes all Units that +// are currently in use as legal tender in any Region. +type QueryIter interface { + // Next returns true if there is a next element available. + // It must be called before any of the other methods are called. + Next() bool + + // Unit returns the unit of the current iteration. + Unit() Unit + + // Region returns the Region for the current iteration. + Region() language.Region + + // From returns the date from which the unit was used in the region. + // It returns false if this date is unknown. + From() (time.Time, bool) + + // To returns the date up till which the unit was used in the region. + // It returns false if this date is unknown or if the unit is still in use. + To() (time.Time, bool) + + // IsTender reports whether the unit is a legal tender in the region during + // the specified date range. + IsTender() bool +} + +// Query represents a set of Units. The default set includes all Units that are +// currently in use as legal tender in any Region. +func Query(options ...QueryOption) QueryIter { + it := &iter{ + end: len(regionData), + date: 0xFFFFFFFF, + } + for _, fn := range options { + fn(it) + } + return it +} + +// NonTender returns a new query that also includes matching Units that are not +// legal tender. +var NonTender QueryOption = nonTender + +func nonTender(i *iter) { + i.nonTender = true +} + +// Historical selects the units for all dates. +var Historical QueryOption = historical + +func historical(i *iter) { + i.date = hist +} + +// A QueryOption can be used to change the set of unit information returned by +// a query. +type QueryOption func(*iter) + +// Date queries the units that were in use at the given point in history. +func Date(t time.Time) QueryOption { + d := toDate(t) + return func(i *iter) { + i.date = d + } +} + +// Region limits the query to only return entries for the given region. +func Region(r language.Region) QueryOption { + p, end := len(regionData), len(regionData) + x := regionToCode(r) + i := sort.Search(len(regionData), func(i int) bool { + return regionData[i].region >= x + }) + if i < len(regionData) && regionData[i].region == x { + p = i + for i++; i < len(regionData) && regionData[i].region == x; i++ { + } + end = i + } + return func(i *iter) { + i.p, i.end = p, end + } +} + +const ( + hist = 0x00 + now = 0xFFFFFFFF +) + +type iter struct { + *regionInfo + p, end int + date uint32 + nonTender bool +} + +func (i *iter) Next() bool { + for ; i.p < i.end; i.p++ { + i.regionInfo = ®ionData[i.p] + if !i.nonTender && !i.IsTender() { + continue + } + if i.date == hist || (i.from <= i.date && (i.to == 0 || i.date <= i.to)) { + i.p++ + return true + } + } + return false +} + +func (r *regionInfo) Region() language.Region { + // TODO: this could be much faster. + var buf [2]byte + buf[0] = uint8(r.region >> 8) + buf[1] = uint8(r.region) + return language.MustParseRegion(string(buf[:])) +} + +func (r *regionInfo) Unit() Unit { + return Unit{r.code &^ nonTenderBit} +} + +func (r *regionInfo) IsTender() bool { + return r.code&nonTenderBit == 0 +} + +func (r *regionInfo) From() (time.Time, bool) { + if r.from == 0 { + return time.Time{}, false + } + return fromDate(r.from), true +} + +func (r *regionInfo) To() (time.Time, bool) { + if r.to == 0 { + return time.Time{}, false + } + return fromDate(r.to), true +} |