Improve reported positions of parsing errors.
This commit is contained in:
parent
b42f91b591
commit
4f4bc52e36
|
@ -73,6 +73,11 @@ impl Pos {
|
||||||
let ptr = s.as_ptr();
|
let ptr = s.as_ptr();
|
||||||
Pos::Raw { ptr }
|
Pos::Raw { ptr }
|
||||||
}
|
}
|
||||||
|
/// Constructg Pos from the end of some other string.
|
||||||
|
pub fn at_end_of(s: &str) -> Self {
|
||||||
|
let ending = &s[s.len()..];
|
||||||
|
Pos::at(ending)
|
||||||
|
}
|
||||||
/// Construct a position from a byte offset.
|
/// Construct a position from a byte offset.
|
||||||
pub fn from_byte(off: usize) -> Self {
|
pub fn from_byte(off: usize) -> Self {
|
||||||
Pos::Byte { off }
|
Pos::Byte { off }
|
||||||
|
|
|
@ -281,7 +281,7 @@ impl<'a> Item<'a> {
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
Some(s) => match s.parse() {
|
Some(s) => match s.parse() {
|
||||||
Ok(r) => Ok(Some(r)),
|
Ok(r) => Ok(Some(r)),
|
||||||
Err(e) => Err(Error::BadArgument(idx, self.pos(), e.to_string())),
|
Err(e) => Err(Error::BadArgument(idx, Pos::at(s), e.to_string())),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,7 +295,7 @@ impl<'a> Item<'a> {
|
||||||
{
|
{
|
||||||
match self.parse_optional_arg(idx) {
|
match self.parse_optional_arg(idx) {
|
||||||
Ok(Some(v)) => Ok(v),
|
Ok(Some(v)) => Ok(v),
|
||||||
Ok(None) => Err(Error::MissingArgument(self.pos())),
|
Ok(None) => Err(Error::MissingArgument(self.arg_pos(idx))),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,13 +310,13 @@ impl<'a> Item<'a> {
|
||||||
/// Try to decode the base64 contents of this Item's associated object.
|
/// Try to decode the base64 contents of this Item's associated object.
|
||||||
pub fn get_obj(&self, want_tag: &str) -> Result<Vec<u8>> {
|
pub fn get_obj(&self, want_tag: &str) -> Result<Vec<u8>> {
|
||||||
match self.object {
|
match self.object {
|
||||||
None => Err(Error::MissingObject("entry", self.pos())),
|
None => Err(Error::MissingObject("entry", self.end_pos())),
|
||||||
Some(obj) => {
|
Some(obj) => {
|
||||||
if obj.tag != want_tag {
|
if obj.tag != want_tag {
|
||||||
Err(Error::WrongObject(self.pos()))
|
Err(Error::WrongObject(Pos::at(obj.tag)))
|
||||||
} else {
|
} else {
|
||||||
base64_decode_multiline(obj.data)
|
base64_decode_multiline(obj.data)
|
||||||
.map_err(|_| Error::BadObjectBase64(self.pos()))
|
.map_err(|_| Error::BadObjectBase64(Pos::at(obj.data)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -334,6 +334,35 @@ impl<'a> Item<'a> {
|
||||||
pub fn offset_in(&self, s: &str) -> Option<usize> {
|
pub fn offset_in(&self, s: &str) -> Option<usize> {
|
||||||
crate::util::str_offset(s, self.kwd)
|
crate::util::str_offset(s, self.kwd)
|
||||||
}
|
}
|
||||||
|
/// Return the position of the n'th argument of this item.
|
||||||
|
///
|
||||||
|
/// If this item does not have a n'th argument, return the
|
||||||
|
/// position of the end of the final argument.
|
||||||
|
pub fn arg_pos(&self, n: usize) -> Pos {
|
||||||
|
let args = self.args_as_vec();
|
||||||
|
if n < args.len() {
|
||||||
|
Pos::at(args[n])
|
||||||
|
} else {
|
||||||
|
self.last_arg_end_pos()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Return the position at the end of the last argument.
|
||||||
|
fn last_arg_end_pos(&self) -> Pos {
|
||||||
|
let args = self.args_as_vec();
|
||||||
|
if args.len() >= 1 {
|
||||||
|
let last_arg = args[args.len() - 1];
|
||||||
|
Pos::at_end_of(last_arg)
|
||||||
|
} else {
|
||||||
|
Pos::at_end_of(self.kwd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Return the position of the end of this object.
|
||||||
|
fn end_pos(&self) -> Pos {
|
||||||
|
match self.object {
|
||||||
|
Some(o) => Pos::at_end_of(o.data),
|
||||||
|
None => self.last_arg_end_pos(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents an Item that might not be present, whose arguments we
|
/// Represents an Item that might not be present, whose arguments we
|
||||||
|
|
Loading…
Reference in New Issue