CronExpression
| GetNextTimeCron
| StopCron
| InfoCron
type TGCommand =
| Start
| Showstat
| Cron of Schdule
let resultSatisfies predicate msg (p : Parser<_, _>) : Parser<_, _> =
let error = messageError msg
fun stream ->
let state = stream.State
let reply = p stream
if reply.Status <> Ok || predicate reply.Result then reply
else
stream.BacktrackTo(state) // backtrack to beginning
Reply(Error, error)
let str s : Parser<string, unit> = pstring s
let pToString p = p |>> fun x -> x.ToString()
let prange p = pipe3 p (pchar '-') p (fun a _ c -> sprintf "%s-%s" a c)
let plist (p : Parser<'a, _>) = sepBy1 p (pchar ',') |>> fun x -> System.String.Join(",", x)
let plapse (p1 : Parser<'a, _>) (p2 : Parser<'b, _>) = pipe3 p1 (pchar '/') p2 (fun a _ c -> sprintf "%s/%s" a c)
let pstar : Parser<string, unit> = pstring "*"
let pquestionMark : Parser<string, unit> = pstring "?"
let pintMinMax min max =
pint32 |> resultSatisfies (fun x -> x <= max && x >= min) (sprintf "This value must be %d-%d" min max)
let [ pfiftyNineS; ptwentyThreeS; pthirtyOneS; pelevenS; psevenS ] : list<Parser<string, unit>> =
[ pToString (pintMinMax 0 59)
pToString (pintMinMax 0 23)
pToString (pintMinMax 1 31)
pToString (pintMinMax 0 11)
pToString (pintMinMax 1 7) ]
let pcronPart (p : Parser<string, unit>) =
choice [ attempt (plapse pstar p)
attempt (plapse p p)
attempt (prange p)
(plist p)
pstar
p ]
let [ pSecOrMin; pHours; pDaysOfMonth; pMonth; pDayOfWeek ] =
[ pcronPart pfiftyNineS
pcronPart ptwentyThreeS
(pquestionMark <|> pcronPart pthirtyOneS)
pcronPart pelevenS
(pquestionMark <|> pcronPart psevenS)]
let pipe6sep p1 p2 p3 p4 p5 p6 func =
p1
>>= fun a ->
(unicodeSpaces1 >>. p2)
>>= fun b ->
(unicodeSpaces1 >>. p3)
>>= fun c ->
(unicodeSpaces1 >>. p4)
>>= fun d ->
(unicodeSpaces1 >>. p5) >>= fun e -> (unicodeSpaces1 >>. p6) >>= fun f -> preturn (func a b c d e f)
let pcron : Parser<string, unit> =
pipe6sep pSecOrMin pSecOrMin pHours pDaysOfMonth pMonth pDayOfWeek
(fun sec min h dom m dow -> System.String.Join(" ", [ sec; min; h; dom; m; dow ]))
let pstartCmd botname = str ("/start" + botname) <|> str "/start" >>% Start
let pshowstatCmd botname = str ("/showstat" + botname) <|> str "/showstat" >>% Showstat
let pcronGetTime = str "get time" >>% GetNextTimeCron
let pcronStop = str "stop" >>% StopCron
let pcronInfo = str "info" >>% InfoCron
let pcronExpression =
pcron >>= (fun x ->
try
(x |> CronExpression)
|> Schdule.StartCron
|> preturn
with :? System.FormatException as fe -> fail (fe.Message))
let pcronCmd botname =
(str ("/cron" + botname) <|> str "/cron") >>. unicodeSpaces1 >>. (pcronExpression <|> pcronGetTime <|> pcronStop <|> pcronInfo ) |>> fun x -> Cron(x)
let pcommand (botname : string) =
unicodeSpaces >>. ((pstartCmd botname) <|> (pcronCmd botname) <|> (pshowstatCmd botname))
коленочный не аккуратный код
Обсуждают сегодня