This can be achieved by using return type from Interface itself. While calling the function in contract B define the return type Interface.struct.
Consider below example:
// Main contract which have struct
contract A {
struct cup{
uint value1;
uint value2;
}
mapping(uint=>cup) public cups;
// Method to add cup struct in mapping.
function addCup(uint _key, uint _value1, uint _value2) public{
cups[_key] = cup(_value1, _value2);
}
}
// Interface with struct and Mapping signature function
interface IA {
// Struct of main contract A
struct cup{
uint value1;
uint value2;
}
// Function signature for mapping
function cups(uint key) view external returns (cup memory);
}
// Secondary contract to access data from main contract
contract B{
function getCup(uint key, address _A) view public returns (IA.cup memory) {
IA.cup memory _cup = IA(_A).cups(key);
return _cup;
}
}
Please check the attached screenshot of output from remix as well.

Note: This is for demo purpose only, The best implementation strategy is to implement Interface IA in contract A and use same struct of interface in contract A and contract B from Interface IA.