using System;
namespace Sprache
{
partial class Parse
{
///
/// Construct a parser that indicates that the given parser
/// is optional. The returned parser will succeed on
/// any input no matter whether the given parser
/// succeeds or not.
///
/// The result type of the given parser.
/// The parser to wrap.
/// An optional version of the given parser.
public static Parser> Optional(this Parser parser)
{
if (parser == null) throw new ArgumentNullException(nameof(parser));
return i =>
{
var pr = parser(i);
if (pr.WasSuccessful)
return Result.Success(new Some(pr.Value), pr.Remainder);
return Result.Success(new None(), i);
};
}
///
/// Constructs the eXclusive version of the Optional{T} parser.
///
/// The result type of the given parser
/// The parser to wrap
/// An eXclusive optional version of the given parser.
///
public static Parser> XOptional(this Parser parser)
{
if (parser == null) throw new ArgumentNullException(nameof(parser));
return i =>
{
var result = parser(i);
if (result.WasSuccessful)
return Result.Success(new Some(result.Value), result.Remainder);
if (result.Remainder.Equals(i))
return Result.Success(new None(), i);
return Result.Failure>(result.Remainder, result.Message, result.Expectations);
};
}
///
/// Construct a parser that indicates that the given parser is optional
/// and non-consuming. The returned parser will succeed on
/// any input no matter whether the given parser succeeds or not.
/// In any case, it won't consume any input, like a positive look-ahead in regex.
///
/// The result type of the given parser.
/// The parser to wrap.
/// A non-consuming version of the given parser.
public static Parser> Preview(this Parser parser)
{
if (parser == null) throw new ArgumentNullException(nameof(parser));
return i =>
{
var result = parser(i);
if (result.WasSuccessful)
return Result.Success(new Some(result.Value), i);
return Result.Success(new None(), i);
};
}
}
}