/** Return a shallow copy of `node` with every body field transformed by `fn`. */
export function mapBodies(node, fn) {
    switch (node.type) {
        case "function":
            return { ...node, body: fn(node.body) };
        case "graphNode":
            return { ...node, body: fn(node.body) };
        case "ifElse": {
            const n = node;
            return { ...n, thenBody: fn(n.thenBody), elseBody: n.elseBody ? fn(n.elseBody) : undefined };
        }
        case "whileLoop":
            return { ...node, body: fn(node.body) };
        case "forLoop":
            return { ...node, body: fn(node.body) };
        case "matchBlock": {
            const n = node;
            return {
                ...n,
                cases: n.cases.map((c) => c.type === "matchBlockCase"
                    ? { ...c, body: fn([c.body])[0] }
                    : c),
            };
        }
        case "handleBlock": {
            const n = node;
            const handler = n.handler.kind === "inline"
                ? { ...n.handler, body: fn(n.handler.body) }
                : n.handler;
            return { ...n, body: fn(n.body), handler };
        }
        case "parallelBlock":
            return { ...node, body: fn(node.body) };
        case "seqBlock":
            return { ...node, body: fn(node.body) };
        case "blockArgument":
            return { ...node, body: fn(node.body) };
        case "functionCall": {
            const n = node;
            if (n.block) {
                return { ...n, block: { ...n.block, body: fn(n.block.body) } };
            }
            return n;
        }
        default:
            return node;
    }
}
