From e2974fef7d7eb37feaad3a10c593a67090298758 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Tue, 8 Mar 2022 14:53:53 +0100 Subject: [PATCH] working-with-schemas.md --- src/SUMMARY.md | 2 +- ... Browser: SimpleChatSimpleChatProtocol.png | Bin 0 -> 61698 bytes ...impleChatSimpleChatProtocolStatus_away.png | Bin 0 -> 19932 bytes src/figures/away-2022-03-08.png | Bin 0 -> 15791 bytes src/guide/schemas/.envrc | 4 + src/guide/schemas/.gitignore | 1 + src/guide/schemas/Makefile | 15 + src/guide/schemas/example.py | 38 ++ src/guide/schemas/rs/chat/mod.rs | 25 ++ .../schemas/rs/chat/simple_chat_protocol.rs | 337 ++++++++++++++++++ src/guide/schemas/simpleChatProtocol.pr | 13 + src/guide/schemas/simpleChatProtocol.prb | 2 + src/guide/schemas/simpleChatProtocol.prs | 6 + .../schemas/ts/gen/simpleChatProtocol.ts | 283 +++++++++++++++ src/guide/working-with-schemas.md | 255 +++++++++++++ 15 files changed, 980 insertions(+), 1 deletion(-) create mode 100644 src/figures/System Browser: SimpleChatSimpleChatProtocol.png create mode 100644 src/figures/a SimpleChatSimpleChatProtocolStatus_away.png create mode 100644 src/figures/away-2022-03-08.png create mode 100644 src/guide/schemas/.envrc create mode 100644 src/guide/schemas/.gitignore create mode 100644 src/guide/schemas/Makefile create mode 100644 src/guide/schemas/example.py create mode 100644 src/guide/schemas/rs/chat/mod.rs create mode 100644 src/guide/schemas/rs/chat/simple_chat_protocol.rs create mode 100644 src/guide/schemas/simpleChatProtocol.pr create mode 100644 src/guide/schemas/simpleChatProtocol.prb create mode 100644 src/guide/schemas/simpleChatProtocol.prs create mode 100644 src/guide/schemas/ts/gen/simpleChatProtocol.ts create mode 100644 src/guide/working-with-schemas.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 2cf1d5d..d87a4ad 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -77,7 +77,7 @@ - [Overview](./guide/index.md) - [Preserves](./guide/preserves.md) -- [Working with schemas]() +- [Working with schemas](./guide/working-with-schemas.md) - [Language-neutral protocols]() - [Rust]() - [Python]() diff --git a/src/figures/System Browser: SimpleChatSimpleChatProtocol.png b/src/figures/System Browser: SimpleChatSimpleChatProtocol.png new file mode 100644 index 0000000000000000000000000000000000000000..1091fdc9adfaf76902784a446fc4b694e4dbcd71 GIT binary patch literal 61698 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

@TYkJev?6-2bpXi8Nr~H*$MMT-r0k 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 PwT;2k)z4*}Q$iB}(;aJo literal 0 HcmV?d00001 diff --git a/src/figures/away-2022-03-08.png b/src/figures/away-2022-03-08.png new file mode 100644 index 0000000000000000000000000000000000000000..d4def94f648b7746f70b6227aeb886716be75410 GIT binary patch literal 15791 zcmbt*cR1Y7_iqppM6_rTgecKF(IX-{5xw`iO7yx&kPtnBRX5Rl@5>Uw2FvQJ3!?YB zSmmyK%J+Nk@BVS0=l-+LJTvp2bLPzK%z2&HnaJ1b3Pc1C32xoGMWm$o^3APVSe2Oa z=-oS*-%Dff;aj()yp>+cYWtclXA*fnK>DE=3$}X_0+`g%FWmjpC|u5=N^TsFz>7z~ zQ09!RTA*ylu0x5C2sVow07ixzY`v`?$=FR|F8i1<$5Hk%iMca#sO4laH;qcY_QZ1l zU)5H(8CF-lBUb%cHPdt+B4BrG0G^pDQR88!@L~}m*7m~@HPGr~XSZ`L&43#C;&i2! zDSqs;_Z^QRaPK?YQ?2ep@Wft$^l{Prk3Us-;IGk9pq`hT4MFIJwh&_J(_f*)(y|GW zlOX(*iMIp0S3BS(Obw=5i<{ErzOnin%wgH6&BU=iho3N}h z4~N5N$8s`k5k4M`9R32|gI323jPXvR#Ws<^%pKsGh@o*^8Z-zM#L>LzmIi6j z3T<22-ADM+n2w`_YuE4iSMJ<7F9?RdbD4F+0RmQuj{1czgoERPyZiR4p)eHD*^%~E z@KBW(sW{{$cn}W|3?8`tjS@NqT+v@gr!3g8#e_H;0;R@EF9?ojkM%q+1}yzAC4zJC z$JbqFE$>nX_s=hZ_XS#9pWZVBW1pxVbWTmc#4I1LM?`Xo0wD4;BW@Hthcj>CuxyQTV zMp9WuOpBvK%+UA{-UdNE5bO0N?0Pu$baZygOX!ea4qy+-Hyo&cx$54->-k#D%s5bP%5E?oA+x04I7 zqq#$(PZj8z*SzulUU2S%PL7AtlP{-P1P=^FrYH3EUJ})X*LrDTVbXtx(+PozF@RzmiU36|>2OK(D zqp|a;ldW+&-bl+hUI0IZE(ng&ol!}*yjIu{`91!CD%W+Vwz|%hrS$@QUH;u{T4ojY zvSIGI@R+FL?1!1O#rI#78n^bW&d0AwyF`s;+;F2|HH|8-8(QYt(5B*T-wZ?B#=DeH zq-9ocy`2z24k;8;Y{E3qqVq$pp=dZ!-6*qKRDLAuHgM9Px_U#QLR_vqMy7DofJ5-go zF5l|sKGFOpUBY=_jl{OWnr?&{UhhRdWF76Qb(4bLwZVzAb4&Tk(5GS>$?b1WH``D= zqseVuSKSzENr^_XJdcoqs&HsE z3;C-;uoV%v>~$OR81&VtHL*F4-jno0t_{iL4ouC%J!v6-5(-FKu6cK|IBMQ&TacVu zwNP)_!3yPVOwgXLhyPS?ERsE)lb9~U8BGAPDDzjkEKhvg4yZaj_jTT=!BHs7o@tO% z%r9*HaV|B10^FTYZ-hn5&ihQ5WJoxm&iS|S$Xzyts}l_!Coe1OL(bLpH#aG7&+dBt zTCQHE+{^laUED>*Y~%apP8^`0LOluEg7aF=Y)VuG88&TFZwGD&YtY+Y_?$yN`g85`1+<PHmQQ@$U!Z7EHjDil?0dV7yh_~m}C z0cn{umyf}he_CqN>LF}#-i^Jd-7)@6Rym*QPEJqv`F8Il(Y)@Gc%rUzfQQ_uILW$8 zhnnstA`Z<*Tfd{fd|Li-njjj1eiT~q_6o^UeQAo$<5!Z|zAbJGWUSk14mb3kb+kZ~ zTlQNH6z`t&#DudN6{D$-tuBq9Bv_5+@#2Yud(a6v89&$X8RHXee7hal(Y@F&EAV`X zq=u;JX&K-Qmo9LDPWIIrysUn5j<$qqh5>Tw54@VAoDvJ^Y%y2C=p#vT{VF+ z?JM;9L}p075!RVyC$MoO{etaT`O#slF+(QwvP7k}d!`qyf}7GP99wRYy)3w*siz8* zO0_Fv3kQv#*by7rj+YU2d4lE}pPW2D!=4&RsfDYfMr}sCNslMExkcpWoIM!MV^O!w z1JLRP=(S1tWC6#}iW%&~5%qYhmp-ZRx(uCpy5t1ugogsG66Yb(te5&`stQjjJ_?6f zzw~u(L6lF%Eb!<|HacJ(XZ&RHyF)!hcZ!r*%b&vG9Raw4*&2c`YKUZjJqyZzrnoVl ze4naZg~4PHbJByOCL>S$n<%=%*T~YNuaUpnIKIa%zz)RsaN%B$6^DD|>bTll+P%Ch zAc3)`suCjHe0KH7o}Bzm_tV$pnX1IpIj&o^ww?IKp4h-r1BYge z(`imV7+&}QXT+PXF%!3FmYk^(L^rVvPj-)({~6?8y{$XdV~NFGKiTq>DKOu;w1K9o zK!|E2(G@fqkCUVM8J8g|g?O6J(vhtNm zS>|Kds6fi$o+5|3uv2{QP%VVhcix1O31y(QjyF7+V>Lt^@FrgVXe%{!(VFAAH*eeO zeFpco)em(6<<>LF*~Z*FF9$@kH2_Q}hkEKGMg_by*e5H4xc$JNU7MRI>1BO#%6h{6 z=`DSOdt63Ti+Hq5l)5v8rD}vG!xT#YTT!pQUXRA6=BV95M*>Rc9=vOcOC@; z+k8{TwaS0~>He|9R$ z^<*r~I&v#5NRG`^^l#pOv-zF5s>IU~G9%?V_?ZTzHeD@WUNm}Xzb0sk(vL}bPW2kx z8vF!awh7X|H}r1m*Y@pABi2zg4*_hgCr9XQL{sd%qB432`SucY{A0&-ygW0fq_Co< zXJO96SWC7dJR#Im|MP5=#xsW_4 z@%Fur)dJmk0ZawY69W@Mfks7TST}-*$wY+@IdM8jplHyxlgQYOQ*X z&Vq5Ga6A z_b=4_i;((8u!f?xsFp)@`Dyg_h4cP*s!II6WZNmppWtXo#pQnCQz|BDbwfxUn=M$i zzPb%yKl!xH^i@%%_@$p#!E(=(w}0aHXa9!R7O2YFi=HKu@#^AZyp1?20w6F~92jIg z#jsUyu~Fri9*pAIU~D*1a8RpKHb5Xw||I4XZ5YGN{(b<-U&}0S%A^H4f##Z%HvlOpx}@XYWlf zV%EENROn4EG>geC@@uEo?jhpPF>o}gD9|g4-JJUrdqoLIP8&VN&g48kB&zNU*uf40nRF?C|Ps1DJ{su-^RPdauVo!ktg}oYXv=;m%}JUb|9fe zrKjaXmBgljUy~=>r`EJMTKI!|aCCd|{=UK7LNc`)gWzCfu%@G^s}x23KFv|#e!Bh) z=P`G!<@1$Anp_)aH4(-&4dSdt^P{^I#~W>Dm0oWhw$)NJ(v~Tv07y30n6Y7{H;Kqq zdhB{*i{z||;06m>zBEX5kVNT~_+ia*>iM#6aK!SDtxY>a&%V6}%gAWi>GvVW^^>f^ z{h3qf3>M46c7*G6noz8iSYTLkZ9{d>cS^wJf*d&2`dY&mD_vk&OI|DgVq95A0O+=q zPqsF+_y(s)VE=v;dg=GC$Hx&tCt4y^noon@JS|AF!S?=~BqcT|%+8zrdg4w0`#op( zZ`4vQbb+1e0dGN58U}Hbqb!ZZ(Xt8|xG;ywuV=JQJB6aXRO?m5`zRfI#9KBxx8_nf z%^4qsi0w0mcT3DhswJTYl78ptby+RIv?g9uPku#DetEw6@kd?hPN=Tvkn*L^3E+~w zVb)0>B$a$RLD?);WX2}4e{?uKUPqhAm|(h+Wdf47>>cZ7CgI~z1heXVxxJ;$D}NNF zkiL9Zlnzpv+^`{7;%EpG!s8veEYOE`XVh^6%I-jKHN4I(3QtB6KYN);IPhtXr#Ho> zl3&F~32C|+?WrQgEtU;q?*z$Z@~@Q+h8Me4cvZU@H^kEtSpYVi2u4k;$bXES^N?zW;xrkJAC087^J>F!x-(H$cGB!@^67N`)p&cGb8f0hz$}bKi7BTx zvTOQN+R`bu2#s+>8XtEcC|~HaM4GQnJ+u_t`_rdKK>=Fk8KRl%Ped`3TPD&Yw(tn81Jm!o#Id3#(RjXZcgE%j69B7kxJ92Ds`hakz zUIp?HhZ5=a))Dk;JI@A&$4vjp!f7WY@by-h#TSE8q4}&261$ z(hk35?{o05Gn(q^3=-Wjby8}EL&v5BgLa34toEA4X7i;esUGfAeqR<+B;2fTG~M-+ zz0DnCzLxwX4dqX+45e^mszS4=5?j3r(gYE#+fXOyGBraOr!oRS>?t ztvv_q6p%fj2-ey&e(MuZAuoi-II_p4L-uh&y_OKfY6{jpUpx=z@LHvQXB_Eu62bhm z%#hxsof+`KU!CrojdK7|!zZc}Ve!_2JND#0w3!cuj9(>(Jd4uEQq|ydDK8N;_9NT` zsPY3`MKMr>Mzc`-{2ssf`X9a7?y-bT5)}qlbMMP&-5&7GRCNQV=wD zz^&Bt@-ZD=Z+^u|K*h)dGP##OoFF}(4CQNuK4Pm|HLZ+I=ZpQG9(JO_M8x83n!=bp z!(L6oz4H>c;hUDAbQjhqadC&kBH2g~T>%T7%JqP#KIftf% zRofTkPYzzj)OOXw?VN_D)#wX4PShDWk^U85cAdj!yR1GFfPSfKzok{iRrR*eiQ?xD z$k&>oz83@1rCd%C)?KnA=SMMub?S+mtxf8LR9^mA7w8eRH2QJ>+aNdh6F0erYNyGZ zSS7{wlg{6`f(E%ye(PJ7=y0`^=e_dSw$QSxQCWPy4JjFA$PEMmy>iO?YCl}6Qc_IE z-bIFtgzG7!E8q}NBYI~yKPO2%d*0W4;m5g$>-4@HXJj@~wyhBpfO5*m8VPo_<>OD$ zYDjHutY)FFY)S2IE$V|?cWOi}(-_2X1(_q7$vWjKBhtjfv5E|$@t@&#Wi?hcwGL#M z>xb3MKg=PR$O2s!)-c0=$85avc=vV+_dNAsmiexyNK0u6lrqLtdlPE^{C^sF37 zZqV|TFYH;;xgkrqqR0(0IDYVRTcJ;M?}A5w!`ATowJdu6@sSk87VTcCMGs z_+P{jmlI(1QMzI+(P(cc%htl6<$%Wdhre|=5F{m{g#7cx`*WHPr$?3vG9-N+{O;u)yAa^2O}%l!vr zU|`v<`TjRqzjXL)y|rsdcw5l)_zcj^)|p6g+Er$bH*WdH=~!ABFRsW@lvGa;KM6ig z9_(96T;6?S#@iUnsvfX1KugXo7j4kc-(R#lY%IFZ?bZgIeIw_$j^+U;#aPps=}Kw@ z%IK8MYM)77l!5nd{8-lcdVQx~#iCZMY-ou+1U|;myrFDVkAz(=@9Qn~yImZ<|KkG_ zOOt1=XiwGG%L+!deQD_4|F`cSCt1}Tb8p*hP%OY?uJ$Paw0}9MUKknw&_%fSwAv4z ziU_@wle?C+NhmTHCoQ<(KMS%ra^q+{8c?W3&+`r)u*rOdG$Te#Ojg&*3nn)UN@p%R z@jPA8c%P0na%N^6l2NDgO{b#lHx4ncxfP3f4g0q!xvN^PO~vShknkZ`(dbbJ%hYKF zRpG`jG5@tQ!rE+<jUGmdkrm(zD4*GLL4gk+%HWAExY_qMLGXcRZq3uU2BIQ5(QUjcaO2U zzz^{`dwV+?Ldf91Bk6p0CLgmQM`dp^kE>Sei3RzHkCeijvui2vyst%R8O^l5tCjjY zn62p92nylrB4^t&{fCOgb(+ED@)6PLexnPRl+qIB!(C^Cza%iWD=)WIcP{9U8zr zHp<8w7Ljmbf&fJS!-AO{{}ZeX$2_S^*mm3^;}6Sy zZSpfoQ&SQy zdpu$JaQyjcI$d!{CT){yCNEG?Cr*$v%D@UG$Zxa{_fxBt4mMG47ut8Uxfq?sj^b0P zsdnd2(&>)grK&Jgwy{xRFG882(^Cu_>pZ^adM$Wv{hk z20we*TPk4?4hH@C--twheil8U?PB2{LP;(H7bi=qp&M7W8Rk*+d*wIe{}z5k)L`%o zTcqJF{pEVbi(aeoafB)TH*wo{^5E0w`7C zs`B-1)o@j8+k2KTR7;ABKUuns9J7)0rOGF{GF*gBwy^cQ<>r$xt`$mQ#7r|Ik8r}E zxg>nQ5E4S6-OZj5%MzI#A909Ed|}M1Q{J1bT;c5^uM$a^wBEavZ4*J`q51H5$~f@* z^avaC9Hrpjll_S;I3JZl(VQF27HDK{Yx&*Mh^|P)!($dCZc7PbHCO#3j@zW&bKek( zFlq0+O(4U}?V>a00r2|K4GJ$d@@;zWl^ns}C(KBm`gmI{ZxKYZ`-z(Jm;QF`Uk4$t zIU@mRy4@E4pwH6WCdkq}KcuVgpxc?TM!TI%1WP3J&*^N<3~us01(swx76rAqz{@ZUPBr?X01=wmr5{5utg;?WeaKz2tjqNC-L9 z^o;VXOeTeTc}=;j*ok4b6d z`J~nbA$wruM&rf}TK6Zk<9+!t~og*t2SPC0%!3 zndx#(M&=ZE0@-4F8--lHMCjpDf>apfNGg}TZ>-0F#Tm=O4IIY1h(F6WN* zlFb5>1l|#kW{pWjf?M9*TuCBWxLhL-^UMQQ^J04r+o&w9FHmbEx4E3%Xt3+iT-+*x z?JiwYAzc!32;8@lPWj$Q9WMP6ZIC-fDeQBEVFqPzHap9R8+ zPV!1yQ7nlVKU1bCy7F%93n20S%}QY|G%zNr&N9WcVl7a_68K<`90grNa_jp_ilG0_;2?#O}JBu1#JUm8DTN7rw zx-ZUXh8H{z35x_SRRyks-GZ_J^J5#t0NhV*WamV9J3d4};AlAXyrGy)Z-E>cpJ>8@gpIalbiZ;a zf?5Z~Kic<^*&MxFpmD;JH`Kj52!ZV6j}SEsO-{Lz)y=6KmZMvAS3(m|>t~|iyk@zv zqt?siBXcBh3UDP&#h-*9;$pM$ex;uCT%7v)r>fMtv)iDC`D(Jc#uJ3Qz5V7{7i|p@RJOY5g?$dim+`pjIp$S1l+}u+SS8d zTFucHD*wc^Ef3a-`)7Ytmf~_n*#D#t&So+{nPof>xCat_$)`!U%`sd39!8di>Owf!1RZ&Pu|!C}yuJt&7Cv^#Yc3ccnF32G5?}Pqa?Kt1 zoo!`y-8;J{DbsPqOL>Ry#D_V!%6w?WVLv;9gyGZLyhPO~R9o{M4nab7DNm5!8 z)0$GpLcepX#)h0Us1{wlfpOBlzbPLU@)RJg@{TY7nv%-W2JKv1AAq|pRU7jVJo&;% zLUeHDL^w?%0oIwz^MkSOqv5AGu_3!(19k;HORO|y_lMr|c@M`&em#TO%)Ff_yCUiP zh(t;rCI~>gwCbD>Tf?}eZB6@h_dTz*K=yw7`>LsDEx-z=*D8bF2ec{yXzi50V$$4xe@spCcg`sjxnUlKtHpR=S zmKkp~q8E})m<9S3Rx(JU$ZDu#3fTJWP^OFP1y_~5cGE~~Zjru9)poMjm!J5iMZl{4 z;R5A0GN1MvI3R$bL$I)7fc z->3gTtIT1pw7mMxEg=nM7p!~;&45{&wkaG!kD5jSCs(z#M!S5C$4f$RmC%@c+qxo zxtNRp(U=Xci)F$WBi|PSp-4IYJe&gXc@nxtyV;gQW*R!hjk45Iyhln@<7|;~rHt-; zGJ+%jha164f6DU`AgLUvn4MI_XlOp3>Vq|p|GgRz(FU&>s+sj%FU$1YIsUjdOO6`c zQ$dZSrUbvtvCGQusOZ=AzCP{Z80|QVD2&vD$2I=uJ*mu+q|8T`nboz};&M}#e(kb- z7&Hj=Z+7p}2lzUtW78lw>g_d@JL2A9vJIgj@?Z@k(~DLOikOs;Gs5uzSi3u&;5w)v zWO5`Wk-+lpz8+wG2Ee)As<%_{eF@;O7ml}vysrPk1I0vu1CI^swm-UeSw8>*9*>L_ z1?x?Y#2tSh&|v)V%7zPD3gfTU_q`F?+ zY4X6C&l};DU*9$>&Cw&S_?nUh0h{`+xb$Z}^BGtjMWoL`>393;cARv@;;iFtB=LI) zEEkHID|jrw=d;v~x$?OPQ)^24q+;fr>GV}qi+^o478i2?zNW~3#Lqwe#drfSD0#hsT0d$hUfW)h$xX=$4l&(mO*h?WN*uU8;7JQuTE*F2 zpz_%Y*8kk~Ft@0DKMB77%HyjBL7RpoWy6JYl`iJi90uQ`iIzq8B5_!q4c;k3j0$VF zCwPU5k{Y&R)(*vmZu6SHmx)*+q;3wu^`h5$?nLWO5tK^wnYaU#0r$43{8+MdJxIRbLIYrR-e6 zw;l>vJ*E*P?NYdaI9qe7;3AS(S{28YipCjgWoW`W^~|KoLm9W%hy30pGoLz2TtYC2 zBzGHDa`CBt&+|?o>L!Jia3bl76x8?Bavt&8=9Z>}NMQ*_Qn;^3(oZ*cDd1j|QR=c+ z!%13O#piJ9JKg?b;F^>6?Ux5{RyhRr@l=wa8_4I(i}iS``dMrXX>o-nAD50HOPG*G z;)WZ?sr84b2M7_a(?i}$5YkS#ff17+2^MjlY9tIEBe}BFypxdc$-6O2II)uhxG;Hkb{3gHQhS z`|moezw@B~t-I0VPrsWl{-0a_RpY`{k5(W0NYoS(=aydu2xmeEv26S(&<<>Za1kHeP+nmn=7 zY%wgpig#yA-b7*Fg@t%GTH?C3a%U>6E;C+XZUu13>-K0`Ugf+)s@DzS z(U1@m{Gm>m%H0(>Z{EQ$u8^ReJHc*JQ*6r=a+edcl~y?@E7w|RthOwhKDZA@r-z)` zk6gD~jVC20&OWA7m*U~ESZ;0|NKiHlum1L>?;?FAEJ*$RNq<37B6;qWDzdUUq{!sS zf^mhISP&HNW?A*ku^=K#;cpgb!10~D?&W!B%bJl!0?LQB{dthPxfuvgPtqIwnJPcUMqnL416-gdqHo zbj}Mbc=)O~K8zjiJ+|wH7VEfK=|h`$>o!(-1GKz$x& z`Fk+RWi}vrWsDVqa!mI4~4^lIO1S51m7`Jms z^0=(qeR592$v>Qd3vtm?KBBranz1hW5O!8&th33F5F{@VL+Z=-i|9v%CO%t3kh!=I zS=P^7z?FaY6j$t&mt?FXhvDnUrzwd|2}C7di2RdLs|qahCX#HLMpE8{x_PeOjUya^ zhzqo}H)Atolx$`uJ zigCvW(ef`W^1FT+Hb5%!>Q?A~UXT;*Rp9pe$YgHN;4tul(|Uf4M_@=bRJGC{{?4@o z21jlMk6N&UlEa@(fJEE4$_(o&&W}m@NaT*p24)H7l_~D?zB{8+s|YbrILn}kl@;b_ zx^r>duYvvf(olOlAb*}s5&O%=+1*u)X%P>;r@kA=WWZ9%%&ENX6m0Z4V$Sa313kbV zG>TmtV8&*0ZvTbH%vU0wT0OQP@)>bFo)qzQg7xb^d9L&fNr*^$I z+rVJFF23Jx+1>SKWTKHk9OrjjRT+gP3LHSt7XQZD+E>^~AFc%&3LG6C z&aMLNiXi+2k|wLH(kq&|mc3J#(}K=37|qf3t}w)l3?}&C5e)#>N9i|+>LTOOnVQbR z&-!NFjb2SMJ}RHrCzz9{K$?6cq|BP$7<)|ck`?w9^H=`Rv1LedNU(Z~{kkGwLO{x4^PS(i(ND3(WN}sZB~BT_bkJGrC>lI0!u4hpZ)Y*8@$kl; z{b|$C-Q`-)nU|4C=}ZxMtUI2W-_YcW>)aSuIiX=xkrl5Q6n@p#elCc4 z9;Ay@C~5+#k4iuBAa+`%PJN$>%e5hJOTU`F#$Iq^!8G!rC8+;l)8k{13R$B{No|Mf z?aKU=^i}v7+7H$)fUmDRpW44@Mc=VuI-5;di$13105YgA9pe5n)Tdz^c0<>cV4>`3w0YHiNfsUp`Sk^_I;|I+j6po z`buYPYO)&U#9WRRP9rg#xX%Qy2Ox|Mz zpdj)dTO%!I!6y`(?PQW!JoyxMWPBqG44kc+MfZc9(~NG3p=FY6`$fswGdACqe@pdn zskU}#`eum8AgHM*N;ixi`6(!RcIz=_=iB~#;Ys^A={(JYyFcA0NBD>8itUNfK-XuG zj!RaY*vRs{ThQxflp@}KWZOwIFxp&8XdAA($}dK)1_rij#UqA>z&9}v{pHNm^4Q?uhr41f-g z1XGQZhs%b<(0Cpczt_%mnZYN90^E(6)Rafg2dA0qFC;@3UL3s;fi%!lCAnN$-R}(C z#;;-S&8ctZG&Z4%eHOdo6Gu>0S~eVIRHo)#ldKF4?ut=YQFH}&jdTk0r;g(njXx>R ztm>=_n+W4t8aOTMHE7Yea5f&NX(Em%m^aY(fFTL?-Ip~P0|e?H3oD*+i+0V6R~7=f zle*6JjP-s)T!TvQ@`{4MP&^90ip^*3hQ0CS=+xw6L;h_DEc?XEd;@iQN;o0!SX3d} zd)YUnSBv5W2N|Hz6K997P8K0{>Y4&)9+Zhw+(juu--hQaDqJlT_JW_J<(ZaQp|!T*A(WLoL`~+WvUXNaR?BC;7O0mb=;3VYEs89?BQXh9PEAJB$ak2yOnoAw64$zKz;B@3bc*z>ae}~@fYCW zgU!3ayTZE2BfgD$CG<^%Pjz;q<4+8Z=8=!U=!@mw)(upa^)R!dW?0Tu6=TNc81j;O zFROJJ+mZYZ773S2XVhGH61*D1zYVn?f ztGB2!3`2II=>zdCg$5o0s2wT+(qOq&gEPU^Yn&T_ig3lPQ6v9=2H+x#$NuqU+F`YuQs@qS~i$k12!nqZG5t%Nr(4@_r+1kR>-*D60XV{ z5*kl-GX>5U>QACmHiK#nI1fjoWC}DCqx&!K{Ee;3Ut#q*ZnCmIjmz`d_!aS?kA0I(oNZ({L&b_P8M~x?j(TSF1R{=40sp z9uNz%h%I73Kk_fO!p?7^LT3fUHbW%#z;y(TKO?=je8IFG-;)_<~LF<9vzDDww) z{mC1U%qP3LCa1k|;{L{t7##AqKn(7@VHy6^gG(rQv3{^olfU{0IkMgR4=(-B*R0`~ z*Q9?^TW^4wAU*a9tLc5LrRxiQi+{ixBIyC&N8dA2zWe{EgXxyP8C!kxWe^AV4OAqS zUV4}AtAq>hBdCFp9p~Qv8`t6!nwY)Z@3jY>)phL2|DD&nPr}Qx+1F3tLCzn@_!rb= zQ(bT;uZSK`d1@}8mkrOfrxN&k1WnmdGRXAn74f47d_x2tHJzAOw>-9g1JflcO_eQv zUdKr64^d!^p<^h49$BhT(xC( tkDO11?0=py^ZjLv)56a&cP@kPGAmi#zcU2JJjA}GB(MIm{Dt}Z{{_^06hi<2 literal 0 HcmV?d00001 diff --git a/src/guide/schemas/.envrc b/src/guide/schemas/.envrc new file mode 100644 index 0000000..e99400e --- /dev/null +++ b/src/guide/schemas/.envrc @@ -0,0 +1,4 @@ +[ -d .venv ] || python -m venv .venv +. .venv/bin/activate +pip install -U preserves +PATH=$PATH:~/src/preserves/implementations/rust/target/debug diff --git a/src/guide/schemas/.gitignore b/src/guide/schemas/.gitignore new file mode 100644 index 0000000..1d17dae --- /dev/null +++ b/src/guide/schemas/.gitignore @@ -0,0 +1 @@ +.venv diff --git a/src/guide/schemas/Makefile b/src/guide/schemas/Makefile new file mode 100644 index 0000000..35e1882 --- /dev/null +++ b/src/guide/schemas/Makefile @@ -0,0 +1,15 @@ +all: simpleChatProtocol.prb rs ts + +simpleChatProtocol.prb: simpleChatProtocol.prs + preserves-schemac .:$< > $@ + +clean: + rm -f simpleChatProtocol.prb + rm -rf rs + rm -rf ts + +rs: simpleChatProtocol.prb + preserves-schema-rs --output-dir rs/chat --prefix chat simpleChatProtocol.prb + +ts: simpleChatProtocol.prs + preserves-schema-ts --output ./ts/gen .:simpleChatProtocol.prs diff --git a/src/guide/schemas/example.py b/src/guide/schemas/example.py new file mode 100644 index 0000000..d974f6e --- /dev/null +++ b/src/guide/schemas/example.py @@ -0,0 +1,38 @@ +from preserves import stringify, schema, parse, Symbol +S = schema.load_schema_file('./simpleChatProtocol.prb') +P = S.simpleChatProtocol + +def hook_for_doctests(): + ''' + >>> P.Present('me') + Present {'username': 'me'} + + >>> stringify(P.Present('me')) + '' + + >>> P.Present.decode(parse('')) + Present {'username': 'me'} + + >>> P.Present.try_decode(parse('')) + Present {'username': 'me'} + + >>> P.Present.try_decode(parse('')) is None + True + + >>> stringify(P.UserStatus('me', P.Status.here())) + '' + + >>> stringify(P.UserStatus('me', P.Status.away('2022-03-08'))) + '>' + + >>> x = P.UserStatus.decode(parse('>')) + >>> x.status.VARIANT + #away + >>> x.status.VARIANT == Symbol('away') + True + ''' + pass + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/src/guide/schemas/rs/chat/mod.rs b/src/guide/schemas/rs/chat/mod.rs new file mode 100644 index 0000000..22dddf9 --- /dev/null +++ b/src/guide/schemas/rs/chat/mod.rs @@ -0,0 +1,25 @@ +pub mod simple_chat_protocol; + +use preserves_schema::support as _support; +use _support::preserves; + +#[allow(non_snake_case)] +pub struct Language { + pub LIT_0_PRESENT: N /* Present */, + pub LIT_1_SAYS: N /* Says */, + pub LIT_4_STATUS: N /* Status */, + pub LIT_3_AWAY: N /* away */, + pub LIT_2_HERE: N /* here */ +} + +impl Default for Language { + fn default() -> Self { + Language { + LIT_0_PRESENT: /* Present */ _support::decode_lit(&vec![179, 7, 80, 114, 101, 115, 101, 110, 116]).unwrap(), + LIT_1_SAYS: /* Says */ _support::decode_lit(&vec![179, 4, 83, 97, 121, 115]).unwrap(), + LIT_4_STATUS: /* Status */ _support::decode_lit(&vec![179, 6, 83, 116, 97, 116, 117, 115]).unwrap(), + LIT_3_AWAY: /* away */ _support::decode_lit(&vec![179, 4, 97, 119, 97, 121]).unwrap(), + LIT_2_HERE: /* here */ _support::decode_lit(&vec![179, 4, 104, 101, 114, 101]).unwrap() + } + } +} diff --git a/src/guide/schemas/rs/chat/simple_chat_protocol.rs b/src/guide/schemas/rs/chat/simple_chat_protocol.rs new file mode 100644 index 0000000..6effe18 --- /dev/null +++ b/src/guide/schemas/rs/chat/simple_chat_protocol.rs @@ -0,0 +1,337 @@ +#![allow(unused_parens)] +#![allow(unused_imports)] + +use std::convert::TryFrom; +use preserves_schema::support as _support; +use _support::Deserialize; +use _support::Parse; +use _support::Unparse; +use _support::preserves; +use preserves::value::Domain; +use preserves::value::NestedValue; + +#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Hash)] +pub struct Present { + pub username: std::string::String +} + +impl preserves::value::Domain for Present {} + +impl<'de, _Value: preserves::value::NestedValue, R: _support::Reader<'de, _Value>> _support::Deserialize<'de, _Value, R> for Present { + fn deserialize(r: &mut R) -> std::result::Result { + r.open_record(None)?; + let mut _tmp0 = _support::B::Type::default(); + _tmp0.shift(Some(_support::B::Item::RecordLabel)); + r.boundary(&_tmp0)?; + match r.next_token(true)? { + preserves::value::Token::Atom(v) => match v.value() { + preserves::value::Value::Symbol(w) if w == "Present" => {} + _ => return Err(_support::ParseError::conformance_error("simpleChatProtocol.Present"))?, + } + _ => return Err(_support::ParseError::conformance_error("simpleChatProtocol.Present"))?, + } + let _tmp1 = (); + _tmp0.shift(Some(_support::B::Item::RecordField)); + r.boundary(&_tmp0)?; + let _tmp2 = r.next_str()?.into_owned(); + r.ensure_complete(_tmp0, &_support::B::Item::RecordField)?; + Ok(Present {username: _tmp2}) + } +} + +impl< + 'a, + _L: Copy + Into<&'a chat::Language<_Value>>, + _Value: preserves::value::NestedValue + 'a +> _support::Parse<_L, _Value> for Present { + fn parse(_ctxt: _L, value: &_Value) -> std::result::Result { + let _tmp0 = value.value().to_record(None)?; + if _tmp0.label() != &<_L as Into<&'a chat::Language<_Value>>>::into(_ctxt).LIT_0_PRESENT { return Err(_support::ParseError::conformance_error("simpleChatProtocol.Present")); } + let _tmp1 = (); + if _tmp0.fields().len() < 1 { return Err(_support::ParseError::conformance_error("simpleChatProtocol.Present")); } + let _tmp2 = (&_tmp0.fields()[0]).value().to_string()?; + Ok(Present {username: _tmp2.clone()}) + } +} + +impl< + 'a, + _L: Copy + Into<&'a chat::Language<_Value>>, + _Value: preserves::value::NestedValue + 'a +> _support::Unparse<_L, _Value> for Present { + fn unparse(&self, _ctxt: _L) -> _Value { + let Present {username: _tmp0} = self; + { + let mut _tmp1 = preserves::value::Record(vec![(&<_L as Into<&'a chat::Language<_Value>>>::into(_ctxt).LIT_0_PRESENT).clone()]); + _tmp1.fields_vec_mut().push(preserves::value::Value::from(_tmp0).wrap()); + _tmp1.finish().wrap() + } + } +} + +#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Hash)] +pub struct Says { + pub who: std::string::String, + pub what: std::string::String +} + +impl preserves::value::Domain for Says {} + +impl<'de, _Value: preserves::value::NestedValue, R: _support::Reader<'de, _Value>> _support::Deserialize<'de, _Value, R> for Says { + fn deserialize(r: &mut R) -> std::result::Result { + r.open_record(None)?; + let mut _tmp0 = _support::B::Type::default(); + _tmp0.shift(Some(_support::B::Item::RecordLabel)); + r.boundary(&_tmp0)?; + match r.next_token(true)? { + preserves::value::Token::Atom(v) => match v.value() { + preserves::value::Value::Symbol(w) if w == "Says" => {} + _ => return Err(_support::ParseError::conformance_error("simpleChatProtocol.Says"))?, + } + _ => return Err(_support::ParseError::conformance_error("simpleChatProtocol.Says"))?, + } + let _tmp1 = (); + _tmp0.shift(Some(_support::B::Item::RecordField)); + r.boundary(&_tmp0)?; + let _tmp2 = r.next_str()?.into_owned(); + _tmp0.shift(Some(_support::B::Item::RecordField)); + r.boundary(&_tmp0)?; + let _tmp3 = r.next_str()?.into_owned(); + r.ensure_complete(_tmp0, &_support::B::Item::RecordField)?; + Ok(Says {who: _tmp2, what: _tmp3}) + } +} + +impl< + 'a, + _L: Copy + Into<&'a chat::Language<_Value>>, + _Value: preserves::value::NestedValue + 'a +> _support::Parse<_L, _Value> for Says { + fn parse(_ctxt: _L, value: &_Value) -> std::result::Result { + let _tmp0 = value.value().to_record(None)?; + if _tmp0.label() != &<_L as Into<&'a chat::Language<_Value>>>::into(_ctxt).LIT_1_SAYS { return Err(_support::ParseError::conformance_error("simpleChatProtocol.Says")); } + let _tmp1 = (); + if _tmp0.fields().len() < 2 { return Err(_support::ParseError::conformance_error("simpleChatProtocol.Says")); } + let _tmp2 = (&_tmp0.fields()[0]).value().to_string()?; + let _tmp3 = (&_tmp0.fields()[1]).value().to_string()?; + Ok(Says {who: _tmp2.clone(), what: _tmp3.clone()}) + } +} + +impl< + 'a, + _L: Copy + Into<&'a chat::Language<_Value>>, + _Value: preserves::value::NestedValue + 'a +> _support::Unparse<_L, _Value> for Says { + fn unparse(&self, _ctxt: _L) -> _Value { + let Says {who: _tmp0, what: _tmp1} = self; + { + let mut _tmp2 = preserves::value::Record(vec![(&<_L as Into<&'a chat::Language<_Value>>>::into(_ctxt).LIT_1_SAYS).clone()]); + _tmp2.fields_vec_mut().push(preserves::value::Value::from(_tmp0).wrap()); + _tmp2.fields_vec_mut().push(preserves::value::Value::from(_tmp1).wrap()); + _tmp2.finish().wrap() + } + } +} + +#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Hash)] +pub enum Status { + Here, + Away { + since: std::boxed::Box + } +} + +impl preserves::value::Domain for Status {} + +fn read_status_here<'de, _Value: preserves::value::NestedValue, R: _support::Reader<'de, _Value>>(r: &mut R) -> std::result::Result { + match r.next_token(true)? { + preserves::value::Token::Atom(v) => match v.value() { + preserves::value::Value::Symbol(w) if w == "here" => {} + _ => return Err(_support::ParseError::conformance_error("simpleChatProtocol.Status::here"))?, + } + _ => return Err(_support::ParseError::conformance_error("simpleChatProtocol.Status::here"))?, + } + let _tmp0 = (); + Ok(Status::Here) +} + +fn read_status_away<'de, _Value: preserves::value::NestedValue, R: _support::Reader<'de, _Value>>(r: &mut R) -> std::result::Result { + r.open_record(None)?; + let mut _tmp0 = _support::B::Type::default(); + _tmp0.shift(Some(_support::B::Item::RecordLabel)); + r.boundary(&_tmp0)?; + match r.next_token(true)? { + preserves::value::Token::Atom(v) => match v.value() { + preserves::value::Value::Symbol(w) if w == "away" => {} + _ => return Err(_support::ParseError::conformance_error("simpleChatProtocol.Status::away"))?, + } + _ => return Err(_support::ParseError::conformance_error("simpleChatProtocol.Status::away"))?, + } + let _tmp1 = (); + _tmp0.shift(Some(_support::B::Item::RecordField)); + r.boundary(&_tmp0)?; + let _tmp2 = TimeStamp::deserialize(r)?; + r.ensure_complete(_tmp0, &_support::B::Item::RecordField)?; + Ok(Status::Away {since: std::boxed::Box::new(_tmp2)}) +} + +impl<'de, _Value: preserves::value::NestedValue, R: _support::Reader<'de, _Value>> _support::Deserialize<'de, _Value, R> for Status { + fn deserialize(r: &mut R) -> std::result::Result { + let _mark = r.mark()?; + match read_status_here(r) { Err(e) if e.is_conformance_error() => r.restore(&_mark)?, result => return result } + match read_status_away(r) { Err(e) if e.is_conformance_error() => r.restore(&_mark)?, result => return result } + Err(_support::ParseError::conformance_error("simpleChatProtocol.Status")) + } +} + +fn parse_status_here< + 'a, + _L: Copy + Into<&'a chat::Language<_Value>>, + _Value: preserves::value::NestedValue + 'a +>(_ctxt: _L, value: &_Value) -> std::result::Result { + if value != &<_L as Into<&'a chat::Language<_Value>>>::into(_ctxt).LIT_2_HERE { return Err(_support::ParseError::conformance_error("simpleChatProtocol.Status::here")); } + let _tmp0 = (); + Ok(Status::Here) +} + +fn parse_status_away< + 'a, + _L: Copy + Into<&'a chat::Language<_Value>>, + _Value: preserves::value::NestedValue + 'a +>(_ctxt: _L, value: &_Value) -> std::result::Result { + let _tmp0 = value.value().to_record(None)?; + if _tmp0.label() != &<_L as Into<&'a chat::Language<_Value>>>::into(_ctxt).LIT_3_AWAY { return Err(_support::ParseError::conformance_error("simpleChatProtocol.Status::away")); } + let _tmp1 = (); + if _tmp0.fields().len() < 1 { return Err(_support::ParseError::conformance_error("simpleChatProtocol.Status::away")); } + let _tmp2 = TimeStamp::parse(_ctxt, (&_tmp0.fields()[0]))?; + Ok(Status::Away {since: std::boxed::Box::new(_tmp2)}) +} + +impl< + 'a, + _L: Copy + Into<&'a chat::Language<_Value>>, + _Value: preserves::value::NestedValue + 'a +> _support::Parse<_L, _Value> for Status { + fn parse(_ctxt: _L, value: &_Value) -> std::result::Result { + if let Ok(r) = parse_status_here(_ctxt, value) { return Ok(r); } + if let Ok(r) = parse_status_away(_ctxt, value) { return Ok(r); } + Err(_support::ParseError::conformance_error("simpleChatProtocol.Status")) + } +} + +impl< + 'a, + _L: Copy + Into<&'a chat::Language<_Value>>, + _Value: preserves::value::NestedValue + 'a +> _support::Unparse<_L, _Value> for Status { + fn unparse(&self, _ctxt: _L) -> _Value { + match self { + Status::Here => (&<_L as Into<&'a chat::Language<_Value>>>::into(_ctxt).LIT_2_HERE).clone(), + Status::Away {since: _tmp0} => { + let mut _tmp1 = preserves::value::Record(vec![(&<_L as Into<&'a chat::Language<_Value>>>::into(_ctxt).LIT_3_AWAY).clone()]); + _tmp1.fields_vec_mut().push(_tmp0.as_ref().unparse(_ctxt)); + _tmp1.finish().wrap() + }, + } + } +} + +#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Hash)] +pub struct TimeStamp(pub std::string::String); + +impl preserves::value::Domain for TimeStamp {} + +impl<'de, _Value: preserves::value::NestedValue, R: _support::Reader<'de, _Value>> _support::Deserialize<'de, _Value, R> for TimeStamp { + fn deserialize(r: &mut R) -> std::result::Result { + let _tmp0 = r.next_str()?.into_owned(); + Ok(TimeStamp(_tmp0)) + } +} + +impl< + 'a, + _L: Copy + Into<&'a chat::Language<_Value>>, + _Value: preserves::value::NestedValue + 'a +> _support::Parse<_L, _Value> for TimeStamp { + fn parse(_ctxt: _L, value: &_Value) -> std::result::Result { + let _tmp0 = value.value().to_string()?; + Ok(TimeStamp(_tmp0.clone())) + } +} + +impl< + 'a, + _L: Copy + Into<&'a chat::Language<_Value>>, + _Value: preserves::value::NestedValue + 'a +> _support::Unparse<_L, _Value> for TimeStamp { + fn unparse(&self, _ctxt: _L) -> _Value { + let TimeStamp(_tmp0) = self; + preserves::value::Value::from(_tmp0).wrap() + } +} + +#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Hash)] +pub struct UserStatus { + pub username: std::string::String, + pub status: Status +} + +impl preserves::value::Domain for UserStatus {} + +impl<'de, _Value: preserves::value::NestedValue, R: _support::Reader<'de, _Value>> _support::Deserialize<'de, _Value, R> for UserStatus { + fn deserialize(r: &mut R) -> std::result::Result { + r.open_record(None)?; + let mut _tmp0 = _support::B::Type::default(); + _tmp0.shift(Some(_support::B::Item::RecordLabel)); + r.boundary(&_tmp0)?; + match r.next_token(true)? { + preserves::value::Token::Atom(v) => match v.value() { + preserves::value::Value::Symbol(w) if w == "Status" => {} + _ => return Err(_support::ParseError::conformance_error("simpleChatProtocol.UserStatus"))?, + } + _ => return Err(_support::ParseError::conformance_error("simpleChatProtocol.UserStatus"))?, + } + let _tmp1 = (); + _tmp0.shift(Some(_support::B::Item::RecordField)); + r.boundary(&_tmp0)?; + let _tmp2 = r.next_str()?.into_owned(); + _tmp0.shift(Some(_support::B::Item::RecordField)); + r.boundary(&_tmp0)?; + let _tmp3 = Status::deserialize(r)?; + r.ensure_complete(_tmp0, &_support::B::Item::RecordField)?; + Ok(UserStatus {username: _tmp2, status: _tmp3}) + } +} + +impl< + 'a, + _L: Copy + Into<&'a chat::Language<_Value>>, + _Value: preserves::value::NestedValue + 'a +> _support::Parse<_L, _Value> for UserStatus { + fn parse(_ctxt: _L, value: &_Value) -> std::result::Result { + let _tmp0 = value.value().to_record(None)?; + if _tmp0.label() != &<_L as Into<&'a chat::Language<_Value>>>::into(_ctxt).LIT_4_STATUS { return Err(_support::ParseError::conformance_error("simpleChatProtocol.UserStatus")); } + let _tmp1 = (); + if _tmp0.fields().len() < 2 { return Err(_support::ParseError::conformance_error("simpleChatProtocol.UserStatus")); } + let _tmp2 = (&_tmp0.fields()[0]).value().to_string()?; + let _tmp3 = Status::parse(_ctxt, (&_tmp0.fields()[1]))?; + Ok(UserStatus {username: _tmp2.clone(), status: _tmp3}) + } +} + +impl< + 'a, + _L: Copy + Into<&'a chat::Language<_Value>>, + _Value: preserves::value::NestedValue + 'a +> _support::Unparse<_L, _Value> for UserStatus { + fn unparse(&self, _ctxt: _L) -> _Value { + let UserStatus {username: _tmp0, status: _tmp1} = self; + { + let mut _tmp2 = preserves::value::Record(vec![(&<_L as Into<&'a chat::Language<_Value>>>::into(_ctxt).LIT_4_STATUS).clone()]); + _tmp2.fields_vec_mut().push(preserves::value::Value::from(_tmp0).wrap()); + _tmp2.fields_vec_mut().push(_tmp1.unparse(_ctxt)); + _tmp2.finish().wrap() + } + } +} diff --git a/src/guide/schemas/simpleChatProtocol.pr b/src/guide/schemas/simpleChatProtocol.pr new file mode 100644 index 0000000..f805728 --- /dev/null +++ b/src/guide/schemas/simpleChatProtocol.pr @@ -0,0 +1,13 @@ + > + ]>> + Says: > + > + ]>> + } + embeddedType: #f + version: 1 +}> diff --git a/src/guide/schemas/simpleChatProtocol.prb b/src/guide/schemas/simpleChatProtocol.prb new file mode 100644 index 0000000..15947af --- /dev/null +++ b/src/guide/schemas/simpleChatProtocol.prb @@ -0,0 +1,2 @@ +´³bundle·µ³simpleChatProtocol„´³schema·³version‘³ definitions·³Says´³rec´³lit³Says„´³tupleµ´³named³who´³atom³String„„´³named³what´³atom³String„„„„„³Status´³orµµ±here´³lit³here„„µ±away´³rec´³lit³away„´³tupleµ´³named³since´³refµ„³ TimeStamp„„„„„„„„³Present´³rec´³lit³Present„´³tupleµ´³named³username´³atom³String„„„„„³ TimeStamp´³atom³String„³ +UserStatus´³rec´³lit³Status„´³tupleµ´³named³username´³atom³String„„´³named³status´³refµ„³Status„„„„„„³ embeddedType€„„„„ \ No newline at end of file diff --git a/src/guide/schemas/simpleChatProtocol.prs b/src/guide/schemas/simpleChatProtocol.prs new file mode 100644 index 0000000..b907784 --- /dev/null +++ b/src/guide/schemas/simpleChatProtocol.prs @@ -0,0 +1,6 @@ +version 1 . +Present = . +Says = . +UserStatus = . +Status = =here / . +TimeStamp = string . diff --git a/src/guide/schemas/ts/gen/simpleChatProtocol.ts b/src/guide/schemas/ts/gen/simpleChatProtocol.ts new file mode 100644 index 0000000..4c419b8 --- /dev/null +++ b/src/guide/schemas/ts/gen/simpleChatProtocol.ts @@ -0,0 +1,283 @@ +import * as _ from "@preserves/core"; + +export const $Present = _.Symbol.for("Present"); +export const $Says = _.Symbol.for("Says"); +export const $Status = _.Symbol.for("Status"); +export const $away = _.Symbol.for("away"); +export const $here = _.Symbol.for("here"); + +let __schema: _.Value | null = null; + +export function _schema() { + if (__schema === null) { + __schema = _.decode<_.GenericEmbedded>(_.Bytes.fromHex("b4b306736368656d61b7b30776657273696f6e91b30b646566696e6974696f6e73b7b30453617973b4b303726563b4b3036c6974b3045361797384b4b3057475706c65b5b4b3056e616d6564b30377686fb4b30461746f6db306537472696e678484b4b3056e616d6564b30477686174b4b30461746f6db306537472696e678484848484b306537461747573b4b3026f72b5b5b10468657265b4b3036c6974b304686572658484b5b10461776179b4b303726563b4b3036c6974b3046177617984b4b3057475706c65b5b4b3056e616d6564b30573696e6365b4b303726566b584b30954696d655374616d708484848484848484b30750726573656e74b4b303726563b4b3036c6974b30750726573656e7484b4b3057475706c65b5b4b3056e616d6564b308757365726e616d65b4b30461746f6db306537472696e678484848484b30954696d655374616d70b4b30461746f6db306537472696e6784b30a55736572537461747573b4b303726563b4b3036c6974b30653746174757384b4b3057475706c65b5b4b3056e616d6564b308757365726e616d65b4b30461746f6db306537472696e678484b4b3056e616d6564b306737461747573b4b303726566b584b306537461747573848484848484b30c656d62656464656454797065808484")); + }; + return __schema; +} + +export const _imports = {} + + +export type Present = {"username": string}; + +export type Says = {"who": string, "what": string}; + +export type UserStatus = {"username": string, "status": Status}; + +export type Status = ({"_variant": "here"} | {"_variant": "away", "since": TimeStamp}); + +export type TimeStamp = string; + + +export function Present(username: string): ( + Present & + {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>} +) {return {"username": username, __as_preserve__() {return fromPresent(this);}};} + +Present.schema = function () { + return {schema: _schema(), imports: _imports, definitionName: _.Symbol.for("Present")}; +} + +export function Says({who, what}: {who: string, what: string}): (Says & {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>}) {return {"who": who, "what": what, __as_preserve__() {return fromSays(this);}};} + +Says.schema = function () { + return {schema: _schema(), imports: _imports, definitionName: _.Symbol.for("Says")}; +} + +export function UserStatus({username, status}: {username: string, status: Status}): ( + UserStatus & + {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>} +) { + return { + "username": username, + "status": status, + __as_preserve__() {return fromUserStatus(this);} + }; +} + +UserStatus.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("UserStatus") + }; +} + +export namespace Status { + export function here(): ( + Status & + {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>} + ) {return {"_variant": "here", __as_preserve__() {return fromStatus(this);}};}; + here.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("Status"), + variant: _.Symbol.for("here") + }; + }; + export function away(since: TimeStamp): ( + Status & + {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>} + ) { + return { + "_variant": "away", + "since": since, + __as_preserve__() {return fromStatus(this);} + }; + }; + away.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("Status"), + variant: _.Symbol.for("away") + }; + }; +} + +export function TimeStamp(value: string): TimeStamp {return value;} + +TimeStamp.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("TimeStamp") + }; +} + +export function asPresent<_embedded = _.GenericEmbedded>(v: _.Value<_embedded>): ( + Present & + {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>} +) { + let result = toPresent(v); + if (result === void 0) throw new TypeError(`Invalid Present: ${_.stringify(v)}`); + return result; +} + +export function toPresent<_embedded = _.GenericEmbedded>(v: _.Value<_embedded>): undefined | ( + Present & + {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>} +) { + let result: undefined | ( + Present & + {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>} + ); + if (_.Record.isRecord<_.Value<_embedded>, _.Tuple<_.Value<_embedded>>, _embedded>(v)) { + let _tmp0: ({}) | undefined; + _tmp0 = _.is(v.label, $Present) ? {} : void 0; + if (_tmp0 !== void 0) { + let _tmp1: (string) | undefined; + _tmp1 = typeof v[0] === 'string' ? v[0] : void 0; + if (_tmp1 !== void 0) {result = {"username": _tmp1, __as_preserve__() {return fromPresent(this);}};}; + }; + }; + return result; +} + +Present.__from_preserve__ = toPresent; + +export function fromPresent<_embedded = _.GenericEmbedded>(_v: Present): _.Value<_embedded> {return _.Record($Present, [_v["username"]]);} + +export function asSays<_embedded = _.GenericEmbedded>(v: _.Value<_embedded>): (Says & {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>}) { + let result = toSays(v); + if (result === void 0) throw new TypeError(`Invalid Says: ${_.stringify(v)}`); + return result; +} + +export function toSays<_embedded = _.GenericEmbedded>(v: _.Value<_embedded>): undefined | (Says & {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>}) { + let result: undefined | (Says & {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>}); + if (_.Record.isRecord<_.Value<_embedded>, _.Tuple<_.Value<_embedded>>, _embedded>(v)) { + let _tmp0: ({}) | undefined; + _tmp0 = _.is(v.label, $Says) ? {} : void 0; + if (_tmp0 !== void 0) { + let _tmp1: (string) | undefined; + _tmp1 = typeof v[0] === 'string' ? v[0] : void 0; + if (_tmp1 !== void 0) { + let _tmp2: (string) | undefined; + _tmp2 = typeof v[1] === 'string' ? v[1] : void 0; + if (_tmp2 !== void 0) { + result = {"who": _tmp1, "what": _tmp2, __as_preserve__() {return fromSays(this);}}; + }; + }; + }; + }; + return result; +} + +Says.__from_preserve__ = toSays; + +export function fromSays<_embedded = _.GenericEmbedded>(_v: Says): _.Value<_embedded> {return _.Record($Says, [_v["who"], _v["what"]]);} + +export function asUserStatus<_embedded = _.GenericEmbedded>(v: _.Value<_embedded>): ( + UserStatus & + {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>} +) { + let result = toUserStatus(v); + if (result === void 0) throw new TypeError(`Invalid UserStatus: ${_.stringify(v)}`); + return result; +} + +export function toUserStatus<_embedded = _.GenericEmbedded>(v: _.Value<_embedded>): undefined | ( + UserStatus & + {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>} +) { + let result: undefined | ( + UserStatus & + {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>} + ); + if (_.Record.isRecord<_.Value<_embedded>, _.Tuple<_.Value<_embedded>>, _embedded>(v)) { + let _tmp0: ({}) | undefined; + _tmp0 = _.is(v.label, $Status) ? {} : void 0; + if (_tmp0 !== void 0) { + let _tmp1: (string) | undefined; + _tmp1 = typeof v[0] === 'string' ? v[0] : void 0; + if (_tmp1 !== void 0) { + let _tmp2: (Status) | undefined; + _tmp2 = toStatus(v[1]); + if (_tmp2 !== void 0) { + result = { + "username": _tmp1, + "status": _tmp2, + __as_preserve__() {return fromUserStatus(this);} + }; + }; + }; + }; + }; + return result; +} + +UserStatus.__from_preserve__ = toUserStatus; + +export function fromUserStatus<_embedded = _.GenericEmbedded>(_v: UserStatus): _.Value<_embedded> { + return _.Record($Status, [_v["username"], fromStatus<_embedded>(_v["status"])]); +} + +export function asStatus<_embedded = _.GenericEmbedded>(v: _.Value<_embedded>): ( + Status & + {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>} +) { + let result = toStatus(v); + if (result === void 0) throw new TypeError(`Invalid Status: ${_.stringify(v)}`); + return result; +} + +export function toStatus<_embedded = _.GenericEmbedded>(v: _.Value<_embedded>): undefined | ( + Status & + {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>} +) { + let _tmp0: ({}) | undefined; + let result: undefined | ( + Status & + {__as_preserve__<_embedded = _.GenericEmbedded>(): _.Value<_embedded>} + ); + _tmp0 = _.is(v, $here) ? {} : void 0; + if (_tmp0 !== void 0) {result = {"_variant": "here", __as_preserve__() {return fromStatus(this);}};}; + if (result === void 0) { + if (_.Record.isRecord<_.Value<_embedded>, _.Tuple<_.Value<_embedded>>, _embedded>(v)) { + let _tmp1: ({}) | undefined; + _tmp1 = _.is(v.label, $away) ? {} : void 0; + if (_tmp1 !== void 0) { + let _tmp2: (TimeStamp) | undefined; + _tmp2 = toTimeStamp(v[0]); + if (_tmp2 !== void 0) { + result = { + "_variant": "away", + "since": _tmp2, + __as_preserve__() {return fromStatus(this);} + }; + }; + }; + }; + }; + return result; +} + +export namespace Status {export const __from_preserve__ = toStatus;} + +export function fromStatus<_embedded = _.GenericEmbedded>(_v: Status): _.Value<_embedded> { + switch (_v._variant) { + case "here": {return $here;}; + case "away": {return _.Record($away, [fromTimeStamp<_embedded>(_v["since"])]);}; + }; +} + +export function asTimeStamp<_embedded = _.GenericEmbedded>(v: _.Value<_embedded>): TimeStamp { + let result = toTimeStamp(v); + if (result === void 0) throw new TypeError(`Invalid TimeStamp: ${_.stringify(v)}`); + return result; +} + +export function toTimeStamp<_embedded = _.GenericEmbedded>(v: _.Value<_embedded>): undefined | TimeStamp { + let _tmp0: (string) | undefined; + let result: undefined | TimeStamp; + _tmp0 = typeof v === 'string' ? v : void 0; + if (_tmp0 !== void 0) {result = _tmp0;}; + return result; +} + +TimeStamp.__from_preserve__ = toTimeStamp; + +export function fromTimeStamp<_embedded = _.GenericEmbedded>(_v: TimeStamp): _.Value<_embedded> {return _v;} + diff --git a/src/guide/working-with-schemas.md b/src/guide/working-with-schemas.md new file mode 100644 index 0000000..63b634d --- /dev/null +++ b/src/guide/working-with-schemas.md @@ -0,0 +1,255 @@ +# Working with schemas + + - [Preserves schema specification](https://preserves.gitlab.io/preserves/preserves-schema.html) + - [Index of Preserves schema tools](https://preserves.gitlab.io/preserves/doc/schema-tools.html) + +[preserves-schemac]: https://preserves.gitlab.io/preserves/doc/preserves-schemac.html + +## Schema source code: *.prs files + +Preserves schemas are written in a syntax that (ab)uses Preserves text syntax as a kind of +S-expression. Schema source code looks like this: + +```preserves-schema +version 1 . +Present = . +Says = . +UserStatus = . +Status = =here / . +TimeStamp = string . +``` + +Conventionally, schema source code is stored in `*.prs` files. In this example, the source code +above is placed in `simpleChatProtocol.prs`. + +## Compiling source code to metaschema instances: *.prb files + +Many of the code generator tools for Preserves schemas require not source code, but instances +of the [Preserves +metaschema](https://preserves.gitlab.io/preserves/preserves-schema.html#appendix-metaschema). +To compile schema source code to metaschema instances, use +[preserves-schemac][]: + +```shell +yarn global add @preserves/schema +preserves-schemac .:simpleChatProtocol.prs > simpleChatProtocol.prb +``` + +Binary-syntax metaschema instances are conventionally stored in `*.prb` files. + +If you have a whole directory tree of `*.prs` files, you can supply just "`.`" without the +"`:`"-prefixed fileglob part. See the [preserves-schemac documentation][preserves-schemac]. + +Converting the `simpleChatProtocol.prb` file to Preserves text syntax lets us read the +metaschema instance corresponding to the source code: + +```shell +cat simpleChatProtocol.prb | preserves-tool convert +``` + +The result: + +```preserves + > + ]>> + Says: > + > + ]>> + Status: + ] + [ + "away" + > + ]>> + ] + ]> + TimeStamp: + UserStatus: > + > + ]>> + } + embeddedType: #f + version: 1 + }> +}> +``` + +## Generating support code from metaschema instances + +Support exists for working with schemas in many languages, including Python, Rust, TypeScript, +Racket, and Squeak Smalltalk. + +### Python + +Python doesn't have a separate compilation step: it loads binary metaschema instances at +runtime, generating classes on the fly. + +After `pip install preserves`, load metaschemas with `preserves.schema.load_schema_file`: + +```python +from preserves import stringify, schema, parse +S = schema.load_schema_file('./simpleChatProtocol.prb') +P = S.simpleChatProtocol +``` + +Then, members of `P` are the definitions from `simpleChatProtocol.prs`: + +```python +>>> P.Present('me') +Present {'username': 'me'} + +>>> stringify(P.Present('me')) +'' + +>>> P.Present.decode(parse('')) +Present {'username': 'me'} + +>>> P.Present.try_decode(parse('')) +Present {'username': 'me'} + +>>> P.Present.try_decode(parse('')) is None +True + +>>> stringify(P.UserStatus('me', P.Status.here())) +'' + +>>> stringify(P.UserStatus('me', P.Status.away('2022-03-08'))) +'>' + +>>> x = P.UserStatus.decode(parse('>')) +>>> x.status.VARIANT +#away +>>> x.status.VARIANT == Symbol('away') +True +``` + +### Rust + +Generate Rust definitions corresponding to a metaschema instance with [preserves-schema-rs][]. +The best way to use it is to integrate it into your `build.rs` (see [the +docs][preserves-schema-rs]), but you can also use it as a standalone command-line tool. + +[preserves-schema-rs]: https://preserves.gitlab.io/preserves/doc/preserves-schema-rs.html + +The following command generates a directory `./rs/chat` containing rust sources for a module +that expects to be called `chat` in Rust code: + +```shell +preserves-schema-rs --output-dir rs/chat --prefix chat simpleChatProtocol.prb +``` + +Representative excerpts from one of the generated files, `./rs/chat/simple_chat_protocol.rs`: + +```rust,noplayground +pub struct Present { + pub username: std::string::String +} +pub struct Says { + pub who: std::string::String, + pub what: std::string::String +} +pub struct UserStatus { + pub username: std::string::String, + pub status: Status +} +pub enum Status { + Here, + Away { + since: std::boxed::Box + } +} +pub struct TimeStamp(pub std::string::String); +``` + +### TypeScript + +Generate TypeScript definitions from schema **sources** (not metaschema instances) using +[preserves-schema-ts][]. Unlike other code generators, this one understands schema source code +directly. + +[preserves-schema-ts]: https://preserves.gitlab.io/preserves/doc/preserves-schema-ts.html + +The following command generates a directory `./ts/gen` containing TypeScript sources: + +```shell +preserves-schema-ts --output ./ts/gen .:simpleChatProtocol.prs +``` + +Representative excerpts from one of the generated files, `./ts/gen/simpleChatProtocol.ts`: + +```typescript +export type Present = {"username": string}; +export type Says = {"who": string, "what": string}; +export type UserStatus = {"username": string, "status": Status}; +export type Status = ({"_variant": "here"} | {"_variant": "away", "since": TimeStamp}); +export type TimeStamp = string; +``` + +### Squeak Smalltalk + +After loading the `Preserves` package from the [Preserves project SqueakSource +page](https://squeaksource.com/Preserves.html), perhaps via + +```smalltalk +Installer squeaksource project: 'Preserves'; install: 'Preserves'. +``` + +you can load and compile the bundle using something like + +```smalltalk +(PreservesSchemaEnvironment fromBundleFile: 'simpleChatProtocol.prb') + category: 'Example-Preserves-Schema-SimpleChat'; + prefix: 'SimpleChat'; + cleanCategoryOnCompile: true; + compileBundle. +``` + +which results in classes whose names are prefixed with `SimpleChat` being created in package +`Example-Preserves-Schema-SimpleChat`. Here's a screenshot of a browser showing the generated +classes: + +![Screenshot of Squeak Browser on class SimpleChatSimpleChatProtocol](<../figures/System Browser: SimpleChatSimpleChatProtocol.png>) + +Exploring the result of evaluating the following expression, which generates a Smalltalk object +in the specified schema, yields the following screenshot: + +```smalltalk +SimpleChatSimpleChatProtocolStatus away + since: (SimpleChatSimpleChatProtocolTimeStamp new value: '2022-03-08') +``` + +![Exploration of a SimpleChatSimpleChatProtocolStatus object](<../figures/a SimpleChatSimpleChatProtocolStatus_away.png>) + +Exploring the result of evaluating the following expression, which generates a Smalltalk object +representing the Preserves value corresponding to the value produced in the previous +expression, yields the following screenshot: + +```smalltalk +(SimpleChatSimpleChatProtocolStatus away + since: (SimpleChatSimpleChatProtocolTimeStamp new value: '2022-03-08')) + asPreserves +``` + +![Exploration of a SimpleChatSimpleChatProtocolStatus preserves value object](<../figures/away-2022-03-08.png>) + +Finally, the following expression parses a valid `Status` string input: + +```smalltalk +SimpleChatSimpleChatProtocolStatus + from: '' parsePreserves + orTry: [] +``` + +If it had been invalid, the answer would have been `nil` (because `[] value` is `nil`).