Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

a way to split long match blocks #215

Open
phaux opened this issue Jan 17, 2024 · 0 comments
Open

a way to split long match blocks #215

phaux opened this issue Jan 17, 2024 · 0 comments
Labels
enhancement New feature or request

Comments

@phaux
Copy link

phaux commented Jan 17, 2024

Is your feature request related to a problem? Please describe.

I'm making a telegram bot and the main part of it is a function like this (I'm not using any library, just typed jsons):

async function handleUpdate(update: TgUpdate) {
  await match(update)
    // bot added to group
    .with({
      my_chat_member: {
        chat: { type: P.union("group", "supergroup") },
        new_chat_member: { status: P.union("member", "administrator") },
      },
    }, async (update) => {
      await handleGroupJoin(update.my_chat_member)
    })
    // command /set_threshold in group chat
    .with({
      message: {
        text: P.string.startsWith("/set_threshold"),
        entities: [{ type: "bot_command", offset: 0 }, ...P.array()],
        chat: { type: P.union("group", "supergroup") },
      },
    }, async (update) => {
      await handleSetThresholdCommand(update.message)
    })
    // reply to command /set_threshold
    .with({
      message: {
        reply_to_message: {
          text: P.string.includes("Tell me the threshold"),
          from: { is_bot: true },
        },
        text: P.string,
      },
    }, async (update) => {
      await handleSetThresholdReply(update.message)
    })
    // message_reaction
    .with({
      message_reaction: {
        chat: { type: P.union("group", "supergroup", "channel") },
      },
    }, async (update) => {
      await handleReaction(update.message_reaction)
    })
    
    // many more match arms later...

    .otherwise(async () => { /* ignore */ })
}

Describe the solution you'd like

I wish there was a way to split the long match block into smaller parts. For example:

export const matchThresholdCommand = (match: _) => match
  // command /set_threshold in group chat
  .with({
    ...
  }, async (update) => {
    ...
  })
  // reply to command /set_threshold
  .with({
    ...
  }, async (update) => {
    ...
  })
async function handleUpdate(update: TgUpdate) {
  await match(update)
    .use(matchThresholdCommand)
    .use(matchOtherCommand)
    // etc
    .otherwise(async () => { /* ignore */ })
}

#209 could improve the api further.

Describe alternatives you've considered

I can match the updates by their type first (all messages, replies, reactions, joins) and then do inner match for each (e.g. for messages, what command it contains), but I would like to split them based on what functionality they provide, not what type they are.

Additional context

I wonder if its possible without any changes to the library and only using the Match type somehow? I tried it but couldn't get the types right:

async function handleUpdate(update: TgUpdate) {
  await withBazCommand(withBarCommand(withFooCommand(match(update))))
    .otherwise(async () => { /* ignore */ })
}

const withFooCommand = <_>(match: Match<_>): Match<_> => match
  .with({...}, async (update) => {...})
  .with({...}, async (update) => {...})

Maybe exporting some helper types for this use case would be enough.

@phaux phaux added the enhancement New feature or request label Jan 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant