// File: oknenavin[P]cxon/examples/json-rpc.cxx
// Function: main
int main() {
    using namespace cxon;
    {   // params array
        auto const call = jsonrpc::make_request(1, "sub", 42, 23);
        std::string req; // serialize call to req
            auto const w = to_bytes(req, call);
        assert(w && req == R"({"jsonrpc":"2.0","id":1,"method":"sub","params":[42,23]})");
    }
    {   // params object
        auto const call = jsonrpc::make_request(1, "sub", jsonrpc::make_napa("x", 42), jsonrpc::make_napa("y", 23));
        std::string req; // serialize call to req
            auto const w = to_bytes(req, call);
        assert(w && req == R"({"jsonrpc":"2.0","id":1,"method":"sub","params":{"x":42,"y":23}})");
    }
    {   // round-trip: req -> res success
        char const res[] = R"({"jsonrpc": "2.0", "result": 19, "id": 1})";
        jsonrpc::response<int> ret; // serialize res to ret
            auto const r = from_bytes(ret, res);
        assert(r && ret.id == 1 && ret.result == 19);
    }
    {   // round-trip: req -> res failure
        char const res[] = R"({
            "jsonrpc": "2.0",
            "error": {"code": 42, "message": "divide by zero", "data": "a black hole has been created somewhere"},
            "id": 1
        })";
        {   // serialize res to ret, error's data will be skipped
            jsonrpc::response<int> ret;
                auto const r = from_bytes(ret, res);
            assert( r &&
                    ret.id == 1 &&
                    ret.error.code == 42 &&
                    ret.error.message == "divide by zero"
            );
        }
        {   // serialize res to ret, error's data is bound to std::string
            jsonrpc::response<int, std::string> ret;
                auto const r = from_bytes(ret, res);
            assert( r &&
                    ret.id == 1 &&
                    ret.error.code == 42 &&
                    ret.error.message == "divide by zero" &&
                    ret.error.data == "a black hole has been created somewhere"
            );
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3a0, %rsp            # imm = 0x3A0
movl $0x0, -0x4(%rbp)
movl $0x2a, -0x24(%rbp)
movl $0x17, -0x28(%rbp)
leaq 0xdfdd(%rip), %rdx      # 0x10304
leaq -0x20(%rbp), %rdi
movq %rdi, -0x340(%rbp)
movl $0x1, %esi
leaq -0x24(%rbp), %rcx
leaq -0x28(%rbp), %r8
callq 0x2ef0
leaq -0x48(%rbp), %rdi
movq %rdi, -0x348(%rbp)
callq 0x21a0
movq -0x348(%rbp), %rsi
movq -0x340(%rbp), %rdx
leaq -0x60(%rbp), %rdi
callq 0x2f30
jmp 0x236d
leaq -0x60(%rbp), %rdi
callq 0x2f60
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x349(%rbp)
jne 0x2387
jmp 0x23ad
leaq 0xdf7a(%rip), %rsi      # 0x10308
leaq -0x48(%rbp), %rdi
callq 0x2f80
movb %al, -0x34a(%rbp)
jmp 0x239f
movb -0x34a(%rbp), %al
movb %al, -0x349(%rbp)
jmp 0x23ad
movb -0x349(%rbp), %al
testb $0x1, %al
jne 0x23b9
jmp 0x23bb
jmp 0x23f4
leaq 0xdf7f(%rip), %rdi      # 0x10341
leaq 0xdfc2(%rip), %rsi      # 0x1038b
movl $0x73, %edx
leaq 0xdfc3(%rip), %rcx      # 0x10398
callq 0x2110
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x20e0
jmp 0x286b
leaq -0x48(%rbp), %rdi
callq 0x20e0
movl $0x2a, -0xb4(%rbp)
leaq 0xdf88(%rip), %rdi      # 0x10396
leaq -0xb4(%rbp), %rsi
callq 0x2ff0
movq %rax, -0xb0(%rbp)
movl %edx, -0xa8(%rbp)
movl $0x17, -0xcc(%rbp)
leaq 0xdf6b(%rip), %rdi      # 0x103a3
leaq -0xcc(%rbp), %rsi
callq 0x2ff0
movq %rax, -0xc8(%rbp)
movl %edx, -0xc0(%rbp)
leaq 0xdeac(%rip), %rdx      # 0x10304
leaq -0xa0(%rbp), %rdi
movq %rdi, -0x358(%rbp)
movl $0x1, %esi
leaq -0xb0(%rbp), %rcx
leaq -0xc8(%rbp), %r8
callq 0x2fb0
leaq -0xf0(%rbp), %rdi
movq %rdi, -0x360(%rbp)
callq 0x21a0
movq -0x360(%rbp), %rsi
movq -0x358(%rbp), %rdx
leaq -0x108(%rbp), %rdi
callq 0x3020
jmp 0x24ad
leaq -0x108(%rbp), %rdi
callq 0x2f60
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x361(%rbp)
jne 0x24ca
jmp 0x24f3
leaq 0xded4(%rip), %rsi      # 0x103a5
leaq -0xf0(%rbp), %rdi
callq 0x2f80
movb %al, -0x362(%rbp)
jmp 0x24e5
movb -0x362(%rbp), %al
movb %al, -0x361(%rbp)
jmp 0x24f3
movb -0x361(%rbp), %al
testb $0x1, %al
jne 0x24ff
jmp 0x2501
jmp 0x253d
leaq 0xdede(%rip), %rdi      # 0x103e6
leaq 0xde7c(%rip), %rsi      # 0x1038b
movl $0x79, %edx
leaq 0xde7d(%rip), %rcx      # 0x10398
callq 0x2110
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x20e0
jmp 0x286b
leaq -0xf0(%rbp), %rdi
callq 0x20e0
movups 0xf09a(%rip), %xmm0     # 0x115ea
movups %xmm0, -0x126(%rbp)
movaps 0xf082(%rip), %xmm0     # 0x115e0
movaps %xmm0, -0x130(%rbp)
movaps 0xf064(%rip), %xmm0     # 0x115d0
movaps %xmm0, -0x140(%rbp)
leaq -0x188(%rbp), %rdi
movq %rdi, -0x370(%rbp)
callq 0x3050
movq -0x370(%rbp), %rsi
leaq -0x1a0(%rbp), %rdi
leaq -0x140(%rbp), %rdx
callq 0x30d0
jmp 0x25a2
leaq -0x1a0(%rbp), %rdi
callq 0x3100
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x371(%rbp)
jne 0x25bf
jmp 0x25e1
xorl %eax, %eax
cmpq $0x1, -0x180(%rbp)
movb %al, -0x371(%rbp)
jne 0x25e1
cmpl $0x13, -0x178(%rbp)
sete %al
movb %al, -0x371(%rbp)
movb -0x371(%rbp), %al
testb $0x1, %al
jne 0x25ed
jmp 0x25ef
jmp 0x262b
leaq 0xde42(%rip), %rdi      # 0x10438
leaq 0xdd8e(%rip), %rsi      # 0x1038b
movl $0x7f, %edx
leaq 0xdd8f(%rip), %rcx      # 0x10398
callq 0x2110
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x188(%rbp), %rdi
callq 0x3120
jmp 0x286b
leaq -0x188(%rbp), %rdi
callq 0x3120
leaq 0xefc2(%rip), %rsi      # 0x11600
leaq -0x260(%rbp), %rdi
movq %rdi, -0x380(%rbp)
movl $0xb1, %edx
callq 0x2120
leaq -0x2a8(%rbp), %rdi
movq %rdi, -0x388(%rbp)
callq 0x3050
movq -0x388(%rbp), %rsi
movq -0x380(%rbp), %rdx
leaq -0x2c0(%rbp), %rdi
callq 0x3140
jmp 0x2685
leaq -0x2c0(%rbp), %rdi
callq 0x3100
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x389(%rbp)
jne 0x26a2
jmp 0x26ee
xorl %eax, %eax
cmpq $0x1, -0x2a0(%rbp)
movb %al, -0x389(%rbp)
jne 0x26ee
xorl %eax, %eax
cmpl $0x2a, -0x290(%rbp)
movb %al, -0x389(%rbp)
jne 0x26ee
leaq -0x288(%rbp), %rdi
leaq 0xdd8a(%rip), %rsi      # 0x1045d
callq 0x2f80
movb %al, -0x38a(%rbp)
jmp 0x26e0
movb -0x38a(%rbp), %al
movb %al, -0x389(%rbp)
jmp 0x26ee
movb -0x389(%rbp), %al
testb $0x1, %al
jne 0x26fa
jmp 0x26fc
jmp 0x2738
leaq 0xdd69(%rip), %rdi      # 0x1046c
leaq 0xdc81(%rip), %rsi      # 0x1038b
movl $0x8e, %edx
leaq 0xdc82(%rip), %rcx      # 0x10398
callq 0x2110
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x2a8(%rbp), %rdi
callq 0x3120
jmp 0x286b
leaq -0x2a8(%rbp), %rdi
callq 0x3120
leaq -0x320(%rbp), %rdi
movq %rdi, -0x398(%rbp)
callq 0x3170
movq -0x398(%rbp), %rsi
leaq -0x338(%rbp), %rdi
leaq -0x260(%rbp), %rdx
callq 0x31f0
jmp 0x2773
leaq -0x338(%rbp), %rdi
callq 0x3100
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x399(%rbp)
jne 0x2790
jmp 0x280c
xorl %eax, %eax
cmpq $0x1, -0x318(%rbp)
movb %al, -0x399(%rbp)
jne 0x280c
xorl %eax, %eax
cmpl $0x2a, -0x308(%rbp)
movb %al, -0x399(%rbp)
jne 0x280c
leaq -0x300(%rbp), %rdi
leaq 0xdc9c(%rip), %rsi      # 0x1045d
callq 0x2f80
movb %al, -0x39a(%rbp)
jmp 0x27ce
movb -0x39a(%rbp), %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x399(%rbp)
jne 0x27e3
jmp 0x280c
leaq -0x2e0(%rbp), %rdi
leaq 0xdccd(%rip), %rsi      # 0x104be
callq 0x2f80
movb %al, -0x39b(%rbp)
jmp 0x27fe
movb -0x39b(%rbp), %al
movb %al, -0x399(%rbp)
jmp 0x280c
movb -0x399(%rbp), %al
testb $0x1, %al
jne 0x2818
jmp 0x281a
jmp 0x2853
leaq 0xdcc5(%rip), %rdi      # 0x104e6
leaq 0xdb63(%rip), %rsi      # 0x1038b
movl $0x98, %edx
leaq 0xdb64(%rip), %rcx      # 0x10398
callq 0x2110
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x320(%rbp), %rdi
callq 0x3220
jmp 0x286b
leaq -0x320(%rbp), %rdi
callq 0x3220
movl -0x4(%rbp), %eax
addq $0x3a0, %rsp            # imm = 0x3A0
popq %rbp
retq
movq -0x68(%rbp), %rdi
callq 0x21d0
nopw %cs:(%rax,%rax)