(cs1: string, cs2:string, pool: AttributePool)
| 753 | * @returns {string} |
| 754 | */ |
| 755 | export const compose = (cs1: string, cs2:string, pool: AttributePool): string => { |
| 756 | const unpacked1 = unpack(cs1); |
| 757 | const unpacked2 = unpack(cs2); |
| 758 | const len1 = unpacked1.oldLen; |
| 759 | const len2 = unpacked1.newLen; |
| 760 | assert(len2 === unpacked2.oldLen, 'mismatched composition of two changesets'); |
| 761 | const len3 = unpacked2.newLen; |
| 762 | const bankIter1 = new StringIterator(unpacked1.charBank); |
| 763 | const bankIter2 = new StringIterator(unpacked2.charBank); |
| 764 | const bankAssem = new StringAssembler(); |
| 765 | |
| 766 | const newOps = applyZip(unpacked1.ops, unpacked2.ops, (op1: Op, op2: Op) => { |
| 767 | const op1code = op1.opcode; |
| 768 | const op2code = op2.opcode; |
| 769 | if (op1code === '+' && op2code === '-') { |
| 770 | bankIter1.skip(Math.min(op1.chars, op2.chars)); |
| 771 | } |
| 772 | const opOut = slicerZipperFunc(op1, op2, pool); |
| 773 | if (opOut.opcode === '+') { |
| 774 | if (op2code === '+') { |
| 775 | bankAssem.append(bankIter2.take(opOut.chars)); |
| 776 | } else { |
| 777 | bankAssem.append(bankIter1.take(opOut.chars)); |
| 778 | } |
| 779 | } |
| 780 | return opOut; |
| 781 | }); |
| 782 | |
| 783 | return pack(len1, len3, newOps, bankAssem.toString()); |
| 784 | }; |
| 785 | |
| 786 | /** |
| 787 | * Returns a function that tests if a string of attributes (e.g. '*3*4') contains a given attribute |
no test coverage detected