code wiki / (root) / nx_send_merge.nx

nx_send_merge.nx source

↩ module page · 128 lines · 5241 B

1// nx_send_merge.nx -- BULK-MERGE: personalized sending to a whole SEGMENT across channels (CRM census E4; the 2// graph-to-send wire). A template with {name} / {occasion} placeholders + a recipient list -> one PERSONALIZED, 3// channel-validated send intent per person: recruiters get personalized outreach, the church segment gets cards, 4// family gets postcards -- email in all incumbents, +physical is the Nishi edge. Composes the nx_send pure core 5// (channel routing + postal/email validation via cmd_intent). Recipient record (tilde-separated because physical 6// destinations carry pipes): name~channel~dest~occasion. STRICT: an unknown {placeholder} is a LOUD template error; 7// a recipient whose dest does not match the channel is REJECTED and tallied, never silently sent. 8// Argless = selftest gate. license_tier: ORIGINAL expect_exit: 0 9import "nx_send.nx" 10const K_MAGIC_4096: i64 = 4096 11const K_MAGIC_1024: i64 = 1024 12 13// personalize tpl into out: {name} + {occasion} replaced; unknown {field} -> -1 (loud). returns length. 14func bm_personalize(tpl: *u8, name: *u8, occ: *u8, out: *u8, cap: i64) -> i64 { 15 var o: i64 = 0 16 var i: i64 = 0 17 while tpl[i] != (0 as u8) { 18 if tpl[i] == (123 as u8) { 19 // read field to '}' 20 let fb: *u8 = sys_mmap(64) 21 var f: i64 = 0 22 i = i + 1 23 while tpl[i] != (125 as u8) { 24 if tpl[i] == (0 as u8) { return 0 - 1 } 25 if f < 63 { fb[f] = tpl[i]; f = f + 1 } 26 i = i + 1 27 } 28 fb[f] = 0 as u8 29 i = i + 1 30 var src: *u8 = 0 as *u8 31 if seq(fb, "name" as *u8) == 1 { src = name } 32 if seq(fb, "occasion" as *u8) == 1 { src = occ } 33 if (src as i64) == 0 { return 0 - 1 } 34 var k: i64 = 0 35 while src[k] != (0 as u8) { if o < cap - 1 { out[o] = src[k]; o = o + 1 } k = k + 1 } 36 } else { 37 if o < cap - 1 { out[o] = tpl[i]; o = o + 1 } 38 i = i + 1 39 } 40 } 41 out[o] = 0 as u8 42 return o 43} 44 45// tilde-field extractor (recipient records; '|' is reserved for postal dests) 46func bm_field(s: *u8, idx: i64, out: *u8, cap: i64) -> i64 { 47 var segi: i64 = 0 48 var t: i64 = 0 49 var i: i64 = 0 50 var found: i64 = 0 51 var go: i64 = 1 52 while go == 1 { 53 let c: i64 = s[i] as i64 54 if c == 0 { go = 0 } 55 if go == 1 { 56 if c == 126 { segi = segi + 1 } else { 57 if segi == idx { found = 1; if t < cap - 1 { out[t] = s[i]; t = t + 1 } } 58 } 59 i = i + 1 60 } 61 } 62 out[t] = 0 as u8 63 return found 64} 65 66// merge one recipient record with the template -> validated send intent. returns 0 queued / 1 rejected / 2 tpl-error 67func bm_one(tpl: *u8, rec: *u8) -> i64 { 68 let nm: *u8 = sys_mmap(256) 69 let ch: *u8 = sys_mmap(64) 70 let ds: *u8 = sys_mmap(512) 71 let oc: *u8 = sys_mmap(128) 72 bm_field(rec, 0, nm, 256) 73 bm_field(rec, 1, ch, 64) 74 bm_field(rec, 2, ds, 512) 75 bm_field(rec, 3, oc, 128) 76 let body: *u8 = sys_mmap(K_MAGIC_4096) 77 let bl: i64 = bm_personalize(tpl, nm, oc, body, K_MAGIC_4096) 78 if bl < 0 { p("BULK-MERGE template ERROR (unknown placeholder) -- fail loud\n" as *u8); return 2 } 79 p("BULK-MERGE to=" as *u8); p(nm); p(" body=" as *u8); p(body); p("\n" as *u8) 80 let rc: i64 = cmd_intent(nm, ch, oc, ds) 81 if rc == 0 { return 0 } 82 return 1 83} 84 85func bm_selftest() -> i64 { 86 p("=== NX-SEND-MERGE SELFTEST (BULK-MERGE: segment -> personalized multi-channel intents) ===\n" as *u8) 87 var ok: i64 = 1 88 let tpl: *u8 = "Dear {name}, happy {occasion} from the Andelins." as *u8 89 90 // personalization is byte-exact 91 let pb: *u8 = sys_mmap(K_MAGIC_1024) 92 let pl: i64 = bm_personalize(tpl, "Grandma Rose" as *u8, "birthday" as *u8, pb, K_MAGIC_1024) 93 p(" personalized: " as *u8); p(pb); p("\n" as *u8) 94 if seq(pb, "Dear Grandma Rose, happy birthday from the Andelins." as *u8) != 1 { ok = 0 } 95 if pl <= 0 { ok = 0 } 96 97 // unknown placeholder is LOUD 98 let bad: i64 = bm_personalize("Hi {name}, your {zip} code" as *u8, "X" as *u8, "Y" as *u8, pb, K_MAGIC_1024) 99 if bad != (0 - 1) { ok = 0 } 100 p(" unknown-placeholder -> " as *u8); pn(bad); p(" (loud)\n" as *u8) 101 102 // the segment: 3 recipients, 3 channels, one invalid dest 103 let recs: *i64 = sys_mmap(8 * 4) as *i64 104 recs[0] = "Grandma Rose~postcard~742 Evergreen Ter|Springfield|IL|62704|US~birthday" as *u8 as i64 105 recs[1] = "Alex~email~alex@example.com~hello" as *u8 as i64 106 recs[2] = "Bob~postcard~bad@example.com~thanks" as *u8 as i64 107 var queued: i64 = 0 108 var rejected: i64 = 0 109 var i: i64 = 0 110 while i < 3 { 111 let r: i64 = bm_one(tpl, recs[i] as *u8) 112 if r == 0 { queued = queued + 1 } 113 if r == 1 { rejected = rejected + 1 } 114 if r == 2 { ok = 0 } 115 i = i + 1 116 } 117 if queued != 2 { ok = 0 } 118 if rejected != 1 { ok = 0 } 119 120 p("BULK-MERGE-SELFTEST queued=" as *u8); pn(queued); p(" rejected=" as *u8); pn(rejected); p(" " as *u8) 121 if ok == 1 { p("verdict=GREEN\n" as *u8); return 0 } 122 p("verdict=RED\n" as *u8) 123 return 1 124} 125 126func main(argc: i64, argv: *i64) -> i64 { 127 return bm_selftest() 128}