fizzbuzz timer

package main

import (
    "context"
    "fmt"
    "time"
)

const (
    FIZZBUZZ = iota
    FIZZ
    BUZZ
    NOTFIZZBUZZ
)

type result byte

func (r result) String() string {
    if r&(1<<FIZZBUZZ) > 0 {
        return "fizzbuzz"
    }
    if r&(1<<FIZZ) > 0 {
        return "fizz"
    }
    if r&(1<<BUZZ) > 0 {
        return "buzz"
    }
    if r&(1<<NOTFIZZBUZZ) > 0 {
        return "notFizzbuzz"
    }
    return "out-of-fizzbuzz"
}

func (r *result) Add(n int) error {
    p := *r
    *r = p | 1<<uint(n)
    return nil
}

func recv(ctx context.Context, in <-chan int) (q int64, r result) {
    defer func() { q = ctx.Value("q").(int64) }()
    for {
        select {
        case x := <-in:
            switch x {
            case FIZZBUZZ:
                defer r.Add(x)
                return
            case FIZZ:
                defer r.Add(x)
            case BUZZ:
                defer r.Add(x)
            case NOTFIZZBUZZ:
                defer r.Add(x)
                return
            }
        case <-ctx.Done():
            return
        }
    }
    return
}

func resPrint(q int64, r result) {
    fmt.Printf("%v %v %v\n", time.Unix(q/1000000000, q%1000000000).Format(time.RubyDate), q, r)
}

func launch(ctx context.Context, out chan<- int) {
    go do(ctx, 15, FIZZBUZZ, out)
    go do(ctx, 3, FIZZ, out)
    go do(ctx, 5, BUZZ, out)
    go dont(ctx, NOTFIZZBUZZ, out)
}

func do(ctx context.Context, d int64, a int, out chan<- int) error {
    q := ctx.Value("q").(int64)
    if q != 0 && q%d == 0 {
        select {
        case out <- a:
        case <-ctx.Done():
            return ctx.Err()
        }
    }
    return nil
}

func dont(ctx context.Context, a int, out chan<- int) error {
    q := ctx.Value("q").(int64)
    if q%3 != 0 && q%5 != 0 {
        select {
        case out <- a:
        case <-ctx.Done():
            return ctx.Err()
        }
    }
    return nil
}

func main() {
    for {
        now := time.Now().UnixNano()
        ctx := context.WithValue(context.Background(), "q", now)
        go func() {
            ctx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
            defer cancel()

            ch := make(chan int)
            go launch(ctx, ch)

            resPrint(recv(ctx, ch))
        }()
    }
}