mpl-token-metadata Rust: Metadata::from_account_info removed — deserialize the borrowed account data instead of fighting &Rc<RefCell<&mut [u8]>>
Symptom: code that read a Metaplex metadata account on-chain with Metadata::from_account_info(&acct) no longer compiles after upgrading mpl-token-metadata — that helper is gone. Reaching for the replacement, Metadata::from_bytes(&ctx.accounts.metadata.to_account_info().data), fails too, because AccountInfo::data is a &Rc<RefCell<&mut [u8]>>, not a &[u8].
The type error sends you looking for an Rc/RefCell conversion trick. The actual answer is to borrow the buffer:
use mpl_token_metadata::accounts::Metadata;
let info = &ctx.accounts.metadata;
let data = info.try_borrow_data()?;
let metadata = Metadata::from_bytes(&data)?; // or:
// let metadata = Metadata::deserialize(&mut data.as_ref())?;Two details that bite: use a deserializer that reads a prefix and ignores the rest — metadata accounts are allocated larger than their current contents, so strict borsh try_from_slice errors on the trailing zero padding, whereas deserialize(&mut data.as_ref()) / from_bytes succeed. And manual deserialization performs no ownership check, so a caller can pass any account whose bytes happen to parse; verify info.owner == &mpl_token_metadata::ID and derive/compare the metadata PDA from the mint before trusting the fields. An unwrap() here is a program panic on any non-metadata account.
If you are in Anchor, prefer letting the framework do it: declare the account with anchor_spl's metadata wrapper (Account<'info, MetadataAccount>), which deserializes on entry and enforces the correct program owner, then read fields off ctx.accounts.metadata directly. Version note: the mpl-token-metadata Rust API was regenerated around the 3.x line, so exact paths differ between 2.x and later releases.
Source: adapted from a Stack Exchange answer by Jimii (question by Effe2), https://solana.stackexchange.com/questions/14888/read-metaplex-metadata-in-rust-anchor — CC BY-SA 4.0