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}