diff options
author | Daniel Mueller <deso@posteo.net> | 2019-01-02 21:14:10 -0800 |
---|---|---|
committer | Daniel Mueller <deso@posteo.net> | 2019-01-02 21:14:10 -0800 |
commit | ecf3474223ca3d16a10f12dc2272e3b0ed72c1bb (patch) | |
tree | 03134a683791176b49ef5c92e8d6acd24c3b5a9b /semver-parser/src/recognize.rs | |
parent | 686f61b75055ecb02baf9d9449525ae447a3bed1 (diff) | |
download | nitrocli-ecf3474223ca3d16a10f12dc2272e3b0ed72c1bb.tar.gz nitrocli-ecf3474223ca3d16a10f12dc2272e3b0ed72c1bb.tar.bz2 |
Update nitrokey crate to 0.2.3
This change updates the nitrokey crate to version 0.2.3. This version
bumps the rand crate used to 0.6.1, which in turn requires an additional
set of dependencies.
Import subrepo nitrokey/:nitrokey at b3e2adc5bb1300441ca74cc7672617c042f3ea31
Import subrepo rand/:rand at 73613ff903512e9503e41cc8ba9eae76269dc598
Import subrepo rustc_version/:rustc_version at 0294f2ba2018bf7be672abd53db351ce5055fa02
Import subrepo semver-parser/:semver-parser at 750da9b11a04125231b1fb293866ca036845acee
Import subrepo semver/:semver at 5eb6db94fa03f4d5c64a625a56188f496be47598
Diffstat (limited to 'semver-parser/src/recognize.rs')
-rw-r--r-- | semver-parser/src/recognize.rs | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/semver-parser/src/recognize.rs b/semver-parser/src/recognize.rs new file mode 100644 index 0000000..c0dd771 --- /dev/null +++ b/semver-parser/src/recognize.rs @@ -0,0 +1,154 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under either of MIT or Apache License, Version 2.0, +// at your option. +// +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file or at +// https://opensource.org/licenses/MIT. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Simple recognizer combinators. + +// This version is similar to a similar one in the "lang" module of +// xi-editor, but is stripped down to only the needed combinators. + +use std::ops; + +pub trait Recognize { + fn p(&self, s: &[u8]) -> Option<usize>; +} + +impl<F: Fn(&[u8]) -> Option<usize>> Recognize for F { + #[inline(always)] + fn p(&self, s: &[u8]) -> Option<usize> { + self(s) + } +} + +pub struct OneByte<F>(pub F); + +impl<F: Fn(u8) -> bool> Recognize for OneByte<F> { + #[inline(always)] + fn p(&self, s: &[u8]) -> Option<usize> { + if s.is_empty() || !self.0(s[0]) { + None + } else { + Some(1) + } + } +} + +impl Recognize for u8 { + #[inline(always)] + fn p(&self, s: &[u8]) -> Option<usize> { + OneByte(|b| b == *self).p(s) + } +} + +/// Use Inclusive(a..b) to indicate an inclusive range. When a...b syntax becomes +/// stable, we can get rid of this and switch to that. +pub struct Inclusive<T>(pub T); + +impl Recognize for Inclusive<ops::Range<u8>> { + #[inline(always)] + fn p(&self, s: &[u8]) -> Option<usize> { + OneByte(|x| x >= self.0.start && x <= self.0.end).p(s) + } +} + +impl<'a> Recognize for &'a [u8] { + #[inline(always)] + fn p(&self, s: &[u8]) -> Option<usize> { + let len = self.len(); + if s.len() >= len && &s[..len] == *self { + Some(len) + } else { + None + } + } +} + +impl<'a> Recognize for &'a str { + #[inline(always)] + fn p(&self, s: &[u8]) -> Option<usize> { + self.as_bytes().p(s) + } +} + +impl<P1: Recognize, P2: Recognize> Recognize for (P1, P2) { + #[inline(always)] + fn p(&self, s: &[u8]) -> Option<usize> { + self.0.p(s).and_then(|len1| + self.1.p(&s[len1..]).map(|len2| + len1 + len2)) + } +} + +/// Choice from two heterogeneous alternatives. +pub struct Alt<P1, P2>(pub P1, pub P2); + +impl<P1: Recognize, P2: Recognize> Recognize for Alt<P1, P2> { + #[inline(always)] + fn p(&self, s: &[u8]) -> Option<usize> { + self.0.p(s).or_else(|| self.1.p(s)) + } +} + +/// Choice from a homogenous slice of parsers. +pub struct OneOf<'a, P: 'a>(pub &'a [P]); + +impl<'a, P: Recognize> Recognize for OneOf<'a, P> { + #[inline] + fn p(&self, s: &[u8]) -> Option<usize> { + for ref p in self.0 { + if let Some(len) = p.p(s) { + return Some(len); + } + } + None + } +} + +pub struct OneOrMore<P>(pub P); + +impl<P: Recognize> Recognize for OneOrMore<P> { + #[inline] + fn p(&self, s: &[u8]) -> Option<usize> { + let mut i = 0; + let mut count = 0; + while let Some(len) = self.0.p(&s[i..]) { + i += len; + count += 1; + } + if count >= 1 { + Some(i) + } else { + None + } + } +} + +pub struct ZeroOrMore<P>(pub P); + +impl<P: Recognize> Recognize for ZeroOrMore<P> { + #[inline] + fn p(&self, s: &[u8]) -> Option<usize> { + let mut i = 0; + while let Some(len) = self.0.p(&s[i..]) { + i += len; + } + Some(i) + } +} |