using System;
using System.Linq;
using static LanguageExt.Prelude;
namespace LanguageExt.Parsec
{
///
/// Represents the parser source string and the parser's
/// positional state.
///
public class PString
{
public readonly T[] Value;
public readonly int Index;
public readonly int EndIndex;
public readonly Option UserState;
public readonly Func TokenPos;
public PString(T[] value, int index, int endIndex, Option userState, Func tokenPos)
{
Value = value ?? throw new ArgumentNullException(nameof(value));
Index = index;
EndIndex = endIndex;
UserState = userState;
TokenPos = tokenPos;
}
public Pos Pos =>
Value.Length == 0
? Pos.Zero
: Index < Value.Length
? TokenPos(Value[Index])
: TokenPos(Value[Value.Length - 1]);
public PString SetValue(T[] value) =>
new PString(value, Index, value.Length, UserState, TokenPos);
public PString SetIndex(int index) =>
new PString(Value, index, EndIndex, UserState, TokenPos);
public PString SetUserState(object? state) =>
new PString(Value, Index, EndIndex, state, TokenPos);
public PString SetEndIndex(int endIndex) =>
new PString(Value, Index, endIndex, UserState, TokenPos);
public override string ToString() =>
$"{typeof(T).Name}({Index}, {EndIndex})";
public static PString Zero(Func tokenPos) =>
new PString(System.Array.Empty(), 0, 0, None, tokenPos);
public PString Cast() where U : T =>
new PString(Value.Cast().ToArray(), Index, EndIndex, UserState, u => TokenPos((T)u));
}
}