soma.cell

Contact Book

Manage contacts with search capability.

Example 082 of the basic Soma programs: a small, commented program that teaches one thing. Every output below was printed by soma 3.2.4 when this page was built.

How it is built

The cell ContactBook keeps 2 memory slots: contacts (Map<String, String>, persistent and consistent) and meta (Map<String, Int>, persistent and consistent). Handlers: add (line 23), list_all (line 37), search (line 46) and demo (line 64).

Generated from soma describe on this file.

The source

082_contacts.cell

// ============================================================================
// 082 — Contact Book
// ============================================================================
// Manage contacts with search capability.
//
// Run:   soma run 082_contacts.cell demo
// Expect:
//   Added: Alice ([email protected])
//   Added: Bob ([email protected])
//   Added: Carol ([email protected])
//   All contacts: 3
//   Search 'mail.com': 2 results
//     Alice: [email protected]
//     Bob: [email protected]

cell ContactBook {

    memory {
        contacts: Map<String, String> [persistent, consistent]
        meta: Map<String, Int> [persistent, consistent]
    }

    on add(name: String, email: String, phone: String) {
        let current = meta.get("next_id")
        if current == () {
            meta.set("next_id", 1)
        }
        let id = meta.get("next_id")
        meta.set("next_id", id + 1)
        let id_str = to_string(id)

        let contact = map("id", id, "name", name, "email", email, "phone", phone)
        contacts.set(id_str, to_json(contact))
        return contact
    }

    on list_all() {
        let keys = contacts.keys()
        let result = list()
        for key in keys {
            result = list(result, from_json(contacts.get(key)))
        }
        return result
    }

    on search(query: String) {
        let all = list_all()
        let q = lowercase(query)
        let results = list()
        for c in all {
            let name_match = contains(lowercase(c.name), q)
            let email_match = contains(lowercase(c.email), q)
            if name_match == true {
                results = list(results, c)
            } else {
                if email_match == true {
                    results = list(results, c)
                }
            }
        }
        return results
    }

    on demo() {
        let c1 = add("Alice", "[email protected]", "555-0001")
        print("Added: {c1.name} ({c1.email})")

        let c2 = add("Bob", "[email protected]", "555-0002")
        print("Added: {c2.name} ({c2.email})")

        let c3 = add("Carol", "[email protected]", "555-0003")
        print("Added: {c3.name} ({c3.email})")

        let all = list_all()
        let count = all.length
        print("All contacts: {count}")

        let found = search("mail.com")
        let found_count = found.length
        print("Search 'mail.com': {found_count} results")
        for c in found {
            print("  {c.name}: {c.email}")
        }

        return "done"
    }
}

What the toolchain says

$ soma check 082_contacts.cell
✓ All checks passed.
$ soma run 082_contacts.cell demo
Added: Alice ([email protected])
Added: Bob ([email protected])
Added: Carol ([email protected])
All contacts: 3
Search 'mail.com': 2 results
  Alice: [email protected]
  Bob: [email protected]
done